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

pytest-mock验证类方法assert_called_with失败问题求助

排查pytest-mock中assert_called_with失败的问题

作为刚上手pytest和mock的新手,碰到assert_called_with失败确实很头疼。我先结合你给出的目标代码,拆解一下常见的坑和解决办法。

首先明确你的目标代码逻辑:Main类的test_func会调用自身的internal_func(20),然后返回计算结果。你的测试应该是想验证internal_func是否确实被传入20调用了对吧?

先把你给出的代码贴出来方便参考:

目标代码(src/main.py)

class Main(object):
    def __init__(self, my_var=None):
        self.var = my_var
    def internal_func(self, var=10):
        my_var = var + 20
        return my_var
    def test_func(self):
        val = self.internal_func(20)
        return val + 40

常见错误原因及修正方案

1. 错误导入/使用mocker fixture

你在测试代码里写了from pytest_mock import mocker,这是错的!pytest-mock的mocker是一个fixture,不需要导入,而是要作为测试函数的参数传入,pytest会自动帮你初始化它。

2. Mock对象选错了(实例方法vs类方法)

新手最容易踩的坑:如果Mock的是类的方法,而不是实例的方法,断言时会因为多了self参数失败。比如:

# 错误示例:Mock类方法
def test_test_func(mocker):
    # Mock的是Main类的internal_func
    mock_internal = mocker.patch('src.main.Main.internal_func')
    mock_internal.return_value = 40
    
    main_instance = Main()
    main_instance.test_func()
    
    # 这里会失败!因为实际调用是 internal_func(self, 20),参数是(main_instance, 20)
    mock_internal.assert_called_with(20)

正确的做法是Mock实例的方法,这样就不会带上self参数的干扰:

# 正确示例:Mock实例方法
def test_test_func(mocker):
    # 先创建实例
    main_instance = Main()
    
    # 针对这个实例,Mock它的internal_func方法
    mock_internal = mocker.patch.object(main_instance, 'internal_func')
    # 给Mock设置返回值,让test_func能正常走完逻辑
    mock_internal.return_value = 40  # 对应原方法internal_func(20)的返回值40
    
    # 调用要测试的方法
    result = main_instance.test_func()
    
    # 验证调用参数:和test_func里的调用完全匹配(位置参数20)
    mock_internal.assert_called_with(20)
    
    # 可选:验证最终返回值是否符合预期
    assert result == 80

3. 参数匹配形式不统一

assert_called_with对参数的形式(位置参数/关键字参数)要求严格。比如如果你的测试代码里写的是mock_internal.assert_called_with(var=20),但实际test_func里是用位置参数self.internal_func(20)调用的,这时候断言就会失败。

如果想忽略参数形式,或者不确定参数是位置还是关键字,可以用mocker.ANY来匹配,比如:

mock_internal.assert_called_with(mocker.ANY)  # 只要被调用就行,不管参数
# 或者只匹配参数值,不管是位置还是关键字
mock_internal.assert_called_once_with(20)

4. 排查小技巧:打印实际调用参数

如果还是搞不清为什么断言失败,可以在断言前打印mock_internal.call_args,看看实际调用时传了什么参数:

print(mock_internal.call_args)
# 比如会输出:call(20) 或者 call(<__main__.Main object at 0x...>, 20)

这样就能直观对比预期参数和实际参数的差异,快速定位问题。

内容的提问来源于stack exchange,提问作者suri

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:56:18