对mock类调用assert_called_with时如何保留自定义返回值
错误原因
unittest.mock.create_autospec不是方法装饰器,它的作用是生成符合指定对象接口的Mock实例,你用它装饰MockA.bar后,自己实现的返回入参的逻辑会被直接替换为自动生成的MagicMock对象,所以调用bar返回的是Mock实例而不是你预期的入参。- 你在测试用例中直接调用
A.bar.assert_called_with校验参数,而实际业务代码中是先实例化A得到实例对象,再调用实例的bar方法,两类调用指向的不是同一个Mock对象,参数校验逻辑本身就会失效。
正确实现方案
不需要自定义Mock类,直接通过patch的autospec能力即可同时满足参数校验、自定义返回值的需求,修复后代码如下:
class B(): def __init__(self): pass def foo(self, arg): a = A() res = a.bar(arg) print(f'foo called with {arg} and returned {res}') assert res == arg return res class A(): def bar(self, arg): return arg import unittest import unittest.mock @unittest.mock.patch("__main__.A", autospec=True) class MyTestCase(unittest.TestCase): def test_case_1(self, mock_A): # 配置实例的bar方法返回传入的第一个参数 mock_A.return_value.bar.side_effect = lambda arg: arg x = B().foo(1) # 校验A类被实例化 mock_A.assert_called_once() # 校验bar方法入参正确 mock_A.return_value.bar.assert_called_once_with(1) def test_case_2(self, mock_A): mock_A.return_value.bar.side_effect = lambda arg: arg x = B().foo(2) mock_A.assert_called_once() mock_A.return_value.bar.assert_called_once_with(2) def test_case_3(self, mock_A): mock_A.return_value.bar.side_effect = lambda arg: arg x = B().foo(3) mock_A.assert_called_once() mock_A.return_value.bar.assert_called_once_with(3) if __name__ == '__main__': unittest.main()
内容的提问来源于stack exchange,提问作者quant
相关产品推荐
相关产品推荐

