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

如何在Python中通过patch模拟类方法返回MagicMock对象

问题分析与解决方案

你的核心问题是patch的目标路径错误,导致自定义的MagicMock没有被实际调用到,反而原Creator的方法调用被mock_creator捕获。以下是具体解决步骤和代码示例:

先明确项目代码结构(基于你的描述)

假设核心业务代码如下:

# utils/SecondLayer.py
class SecondLayer:
    def do_something_second_layer(self):
        pass
# utils/Creator.py
from .SecondLayer import SecondLayer

class Creator:
    @staticmethod
    def get_second_layer():
        return SecondLayer()
# utils/User.py
from .Creator import Creator

class User:
    def execute(self):
        # 调用Creator的静态方法获取SecondLayer实例,再调用其方法
        sl_instance = Creator.get_second_layer()
        sl_instance.do_something_second_layer()

错误原因:patch路径不匹配

你可能直接patch了utils.Creator.Creator.get_second_layer,但User模块中导入的Creator是独立的引用,测试时User代码依然使用原模块的方法,导致自定义MagicMock从未被调用。

正确实现方式

1. 针对被测试代码的导入路径patch

必须patchutils.User.Creator.get_second_layer(即User模块中实际使用的Creator引用),而非原Creator模块的路径。

2. 注入自定义MagicMock并跟踪调用

# tests/test_user.py
from unittest.mock import patch, MagicMock
from utils.User import User

def test_second_layer_call():
    # 创建自定义MagicMock实例
    mock_second_layer = MagicMock()
    
    # 关键:patch User模块中导入的Creator的get_second_layer方法
    with patch('utils.User.Creator.get_second_layer', return_value=mock_second_layer):
        user = User()
        user.execute()
        
        # 现在可以正常捕获调用记录
        assert mock_second_layer.do_something_second_layer.called
        print(mock_second_layer.mock_calls)  # 输出: [call.do_something_second_layer()]

3. 装饰器写法(可选)

如果习惯用装饰器,同样要注意patch路径:

from unittest.mock import patch, MagicMock
from utils.User import User

@patch('utils.User.Creator.get_second_layer')
def test_second_layer_call_decorator(mock_get_sl):
    mock_second_layer = MagicMock()
    mock_get_sl.return_value = mock_second_layer
    
    user = User()
    user.execute()
    
    assert mock_second_layer.do_something_second_layer.called

额外检查点

  • 确认patch路径与被测试代码的导入逻辑完全匹配(比如如果User中是import utils.Creator,则patch路径应为utils.User.utils.Creator.Creator.get_second_layer)
  • 确保所有测试代码都在patch的上下文(with代码块或装饰器作用域)内执行
  • 若使用类方法而非静态方法,patch路径逻辑一致,只需调整方法名

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 18:35:15