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

如何用unittest.mock.patch模拟类的__call__方法?

如何Mock类实例的__call__特殊方法

我需要Mock在ContainerClass的__init__方法中实例化的ClassToBeMocked对象,替换它的__call__特殊方法。目前代码对普通方法有效,但__call__方法不生效,具体代码、当前输出和期望输出如下:

代码示例

from unittest.mock import patch, Mock, MagicMock

class ClassToBeMocked:
    def __call__(self, x):
            return 42

    def regular_method(self, x):
            return 42

class ContainerClass:
    def __init__(self):
        self.runner = ClassToBeMocked()

    def run_a(self):
        return self.runner(x="x")
        
    def run_b(self):
        return self.runner.regular_method(x="x")
    
    
with patch("__main__.ClassToBeMocked") as mock:
    instance = mock.return_value
    instance.__call__ = MagicMock(return_value="Hey")
    instance.regular_method = MagicMock(return_value="Hey")
    
    test = ContainerClass()
    print(test.run_a())
    print(test.run_b())

当前输出

<MagicMock name='ClassToBeMocked()()' id='140033866116784'>
Hey

期望输出

Hey
Hey

问题原因

MagicMock的特殊方法(如__call__)无法通过直接赋值新的MagicMock对象来覆盖,因为MagicMock会动态生成这些特殊方法的代理逻辑,直接赋值的对象不会被实际调用时使用。

解决方法

有两种简单的修改方式可以实现需求:

方式一:设置mock实例的return_value

调用mock实例本身等价于调用它的__call__方法,因此直接设置实例的return_value即可:

with patch("__main__.ClassToBeMocked") as mock:
    instance = mock.return_value
    # 替换原有的instance.__call__赋值语句
    instance.return_value = "Hey"
    instance.regular_method = MagicMock(return_value="Hey")
    
    test = ContainerClass()
    print(test.run_a())  # 输出 Hey
    print(test.run_b())  # 输出 Hey

方式二:设置__call__方法的return_value

不重新赋值__call__,而是直接修改原有__call__方法的返回值:

with patch("__main__.ClassToBeMocked") as mock:
    instance = mock.return_value
    # 替换原有的instance.__call__赋值语句
    instance.__call__.return_value = "Hey"
    instance.regular_method = MagicMock(return_value="Hey")
    
    test = ContainerClass()
    print(test.run_a())  # 输出 Hey
    print(test.run_b())  # 输出 Hey

处理带参数的场景

如果需要根据传入的参数返回不同结果,可以使用side_effect:

instance.side_effect = lambda x: f"Hey with parameter: {x}"

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 19:50:16