如何在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
相关产品推荐
相关产品推荐

