You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

对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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 03:06:02