单元测试中,参数化未使用的Mock输入,测试结构是否正确?
关于Mock参数化与测试结构的问题解答
核心问题解答
不需要为未使用的Mock输入做参数化
参数化的意义是验证代码在不同输入下的行为差异。如果某个Mock的输入值完全没在测试逻辑里用到,也不会影响被测试函数的执行结果,那参数化这个值纯粹是冗余操作,只会增加不必要的测试用例,浪费执行资源。你的测试结构存在问题
从代码来看,你在@pytest.mark.parametrize里定义了mock_download_result,但:- 测试函数里既没有使用这个参数,也没有将它关联到
download_single_file_from_s3的Mock上; - 你已经通过
return_value=None固定了这个Mock的返回值,就算参数化mock_download_result,也不会改变Mock的行为。
这种情况下,参数化mock_download_result完全没有意义,测试结构是不合理的。
- 测试函数里既没有使用这个参数,也没有将它关联到
修正方案
情况1:确实需要测试download_single_file_from_s3的不同返回值
如果你的目标是验证pass1在download_single_file_from_s3返回不同结果时的行为,那需要把参数化的值绑定到Mock上,修改代码如下:
@pytest.mark.parametrize('mock_finfo, mock_download_result', [ ({'ready': False}, None), ({'ready': False}, 'test_content'), ({'ready': True}, b'binary_data') ]) @mock.patch('jobserve.tasks.parsing_pipeline._pcontrol.pass1_parse') @mock.patch('jobserve.tasks.parsing_pipeline.download_single_file_from_s3') # 移除提前设置的return_value def test_parseable_files_pass1_force_False(mock_download_single_file_from_s3, mock_pass1_parse, mock_finfo, mock_download_result): # 将参数化的值赋值给Mock的返回值 mock_download_single_file_from_s3.return_value = mock_download_result mock_parseable_files.return_value = mock_finfo parser_code = 'lse' data_file_group = 'equities2' dte = 20190501 parser_extra_params = {'force': True} try: pass1(parser_code) except ValueError as ve: assert False, f"pass1 raised a ValueError {ve}"
情况2:download_single_file_from_s3的返回值不影响测试逻辑
如果这个Mock的返回值不会改变pass1的执行结果,那直接删掉冗余的参数化项,简化测试:
@pytest.mark.parametrize('mock_finfo', [ {'ready': False}, {'ready': True} ]) @mock.patch('jobserve.tasks.parsing_pipeline._pcontrol.pass1_parse') @mock.patch('jobserve.tasks.parsing_pipeline.download_single_file_from_s3', return_value=None) def test_parseable_files_pass1_force_False(mock_download_single_file_from_s3, mock_pass1_parse, mock_finfo): mock_parseable_files.return_value = mock_finfo parser_code = 'lse' data_file_group = 'equities2' dte = 20190501 parser_extra_params = {'force': True} try: pass1(parser_code) except ValueError as ve: assert False, f"pass1 raised a ValueError {ve}"
内容的提问来源于stack exchange,提问作者Patrick_Chong
相关产品推荐
相关产品推荐

