pytest中mock.patch.object模拟类方法不生效问题
pytest 类方法mock不生效问题解决
问题根因
当前测试代码存在两个直接导致mock失效的错误:
- 自定义的
fake_do_verify函数没有传入@patch.object作为替换实现,装饰器默认生成的Mock对象被测试方法的形参fake_do_verify接收,和全局定义的假函数重名但完全不是同一个对象,默认Mock对象调用后返回的是新的Mock实例,永远不会返回预期的{'value': False}。 - 原
do_verify是类实例方法,调用时会自动传入实例self作为第一个参数,定义的假函数没有预留self形参位置,就算绑定到类方法上,调用时也会触发参数不匹配报错;另外代码中开启了autospec=True,这个参数会强制校验方法签名,会进一步放大参数不匹配的问题。
可运行的修复写法
写法1:绑定自定义假函数
直接把写好的假函数作为new参数传给patch装饰器,注意给假函数加上self形参匹配实例方法签名,此时测试方法不需要额外接收mock参数:
from unittest.mock import patch import pytest from main import First # 注意第一个形参self,匹配实例方法调用规则 def fake_do_verify(self): print('works') return {'value': False} class TestMain(object): @patch.object(First, 'do_verify', new=fake_do_verify) def test_main(self): with pytest.raises(Exception): First()
写法2:直接配置Mock返回值
不需要单独定义假函数,利用patch自动生成的Mock对象,直接配置其返回值即可,这种写法更简洁:
from unittest.mock import patch import pytest from main import First class TestMain(object): @patch.object(First, 'do_verify') def test_main(self, mock_do_verify): mock_do_verify.return_value = {'value': False} with pytest.raises(Exception): First()
原代码失效的具体逻辑
原测试代码运行时,被替换的do_verify是patch自动生成的Mock对象,调用该对象返回的是默认Mock实例,执行ret_val['value']时拿到的还是Mock类型对象,Mock实例 is False的判断结果恒为False,永远不会进入抛出Exception的分支,因此pytest会提示DID NOT RAISE <class 'Exception'>的报错。
内容的提问来源于stack exchange,提问作者Gaurav
相关产品推荐
相关产品推荐

