pytest中patch与patch.object无法触发类方法异常的原因咨询
问题原因与修复方案
问题原因
你用@patch把load_data模块里的DataSet类替换成了MagicMock(即ds_mock),随后尝试用patch.object修改这个Mock类的load_data方法,但这种方式不会生效:
当slow_load()调用DataSet()创建实例时,返回的是ds_mock.return_value(一个全新的Mock实例),这个实例的load_data方法是独立生成的,不会继承你给类Mock设置的side_effect。简单来说,你修改的是类级别的Mock方法,但实际业务代码调用的是实例级别的Mock方法,两者没有关联。
而test_slow_load_01能正常运行,是因为它直接patch了DataSet.load_data这个类的方法属性,当实例调用load_data时,会从类上查找该方法,因此side_effect能正常触发。
修复后的测试代码
方案一:直接配置Mock实例的方法(推荐)
不需要额外使用patch.object,直接给Mock类的返回值(即实例对象)的load_data设置side_effect:
@patch("python_tools.pytest_samples.load_data.DataSet") def test_slow_load_02(ds_mock): # 给DataSet实例的load_data方法设置异常侧效应 ds_mock.return_value.load_data.side_effect = Exception('URLError') with pytest.raises(Exception) as excinfo: slow_load() assert str(excinfo.value) == 'URLError'
方案二:用patch.object修改实例级Mock
如果坚持使用patch.object,需要针对Mock实例(即ds_mock.return_value)进行patch:
@patch("python_tools.pytest_samples.load_data.DataSet") def test_slow_load_02(ds_mock): with patch.object(ds_mock.return_value, 'load_data', side_effect=Exception('URLError')): with pytest.raises(Exception) as excinfo: slow_load() assert str(excinfo.value) == 'URLError'
内容的提问来源于stack exchange,提问作者sfgroups
相关产品推荐
相关产品推荐

