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

如何在Python中创建可相加的Mock对象以测试代码?

解决Mock对象加法及调用验证问题

这里有两种可靠的方法来解决你的问题,既可以让Mock支持加法操作,又能精确验证整个调用链是否符合预期:

方案一:为特定Mock属性定制加法行为(推荐用于单一场景)

这种方法直接针对m.a的加法行为做定制,能精准捕获加法结果并验证后续的c()调用:

import unittest
import unittest.mock

def to_be_tested(x): 
    return round((x.a + x.b).c()) 

class Test_X(unittest.TestCase): 
    def test_x(self): 
        m = unittest.mock.Mock()
        
        # 创建一个Mock作为加法运算的返回结果,它会被用来调用.c()
        sum_mock = unittest.mock.Mock()
        # 给m.a的__add__方法设置返回值为sum_mock
        m.a.__add__ = unittest.mock.Mock(return_value=sum_mock)
        
        # 执行被测函数
        to_be_tested(m)
        
        # 验证m.a的加法方法被正确调用,参数是m.b
        m.a.__add__.assert_called_once_with(m.b)
        # 验证sum_mock的c()方法被调用
        sum_mock.c.assert_called_once()
        
        # 额外:如果需要验证round的结果,可以给sum_mock.c()设置返回值
        sum_mock.c.return_value = 3.7
        result = to_be_tested(m)
        self.assertEqual(result, 4)

方案二:创建支持加法的通用Mock子类(适合多场景复用)

如果你的测试中需要大量支持加法的Mock,可以自定义一个Mock子类,让所有实例默认支持加法:

import unittest
import unittest.mock

def to_be_tested(x): 
    return round((x.a + x.b).c()) 

class AddableMock(unittest.mock.Mock):
    def __add__(self, other):
        # 加法返回另一个AddableMock实例,确保后续能调用.c()
        return AddableMock()

class Test_X(unittest.TestCase): 
    def test_x(self): 
        m = AddableMock()
        
        # 执行被测函数
        to_be_tested(m)
        
        # 验证m.a和m.b被访问过
        self.assertIn(('a',), m.mock_calls)
        self.assertIn(('b',), m.mock_calls)
        
        # 如果需要验证加法后的c()调用,可以进一步跟踪:
        class TrackedAddableMock(AddableMock):
            def __init__(self, *args, **kwargs):
                super().__init__(*args, **kwargs)
                self.add_result = None
            
            def __add__(self, other):
                self.add_result = TrackedAddableMock()
                return self.add_result
        
        m = TrackedAddableMock()
        to_be_tested(m)
        # 验证加法结果的c()方法被调用
        m.a.add_result.c.assert_called_once()

为什么你之前的尝试失败?

你之前设置m.a.__add__ = lambda a, b: unittest.mock.Mock(a, b)时,错误地把a和b作为Mock的spec参数传入了,这不是你想要的——你应该直接创建一个无参数的Mock实例:lambda a, b: unittest.mock.Mock()。另外,AttributeError大概率是因为这个参数错误导致Mock初始化异常,进而没有生成预期的c属性。

总结

  • 如果你只需要验证单一的调用链,方案一更直接,能精确控制每个Mock的行为并验证;
  • 如果你有多个需要支持加法的Mock场景,方案二的自定义子类能减少重复代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:23:05