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

如何在测试a.do_something时Mock b中导入的my_other_func?

正确Mock跨模块底层依赖的方法

问题场景

现有代码结构如下:

a.py

from b import my_func

def do_something():
    my_func()

b.py

from c import my_other_func  # 测试时需要Mock这个函数(屏蔽其内部数据库调用)
def my_func():
    my_other_func()

需要为a.do_something()编写单元测试,要求保留b.my_func的原有逻辑,仅Mock底层的my_other_func,但尝试mock.patch("a.b.my_other_func")、mock.patch("b.my_other_func")均未正确生效。

解决方案

核心要理解Python的模块引用机制:当b.py执行from c import my_other_func时,会将c.my_other_func的引用复制到b模块的命名空间中,b.my_func实际调用的是b模块内的这个引用,而非c模块的原函数。

正确的Patch路径

必须针对b模块内的my_other_func引用进行Patch,即使用路径"b.my_other_func",但要注意导入顺序:必须先完成Patch,再导入被测试的a或b模块,否则原引用会被提前加载,Patch无法覆盖。

测试代码示例

用装饰器实现

from unittest import mock, unittest

class TestDoSomething(unittest.TestCase):
    @mock.patch("b.my_other_func")
    def test_do_something(self, mock_my_other_func):
        # 延迟导入被测试模块,确保Patch已生效
        from a import do_something
        
        do_something()
        # 验证Mock函数被调用
        mock_my_other_func.assert_called_once()

if __name__ == "__main__":
    unittest.main()

用上下文管理器实现

from unittest import mock

def test_do_something():
    with mock.patch("b.my_other_func") as mock_my_other_func:
        from a import do_something
        do_something()
        mock_my_other_func.assert_called_once()

常见失败原因

  • 使用"a.b.my_other_func"路径:错误,a模块仅导入了b.my_func,不存在a.b子模块,路径无效。
  • Patch前提前导入a/b:如果测试文件在Patch执行前就导入了a或b,b模块内的my_other_func引用已被固定,后续Patch无法覆盖这个引用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 03:50:26