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

Python Unittest如何Mock被__init__.py导入的外部函数?

解决Mock失效问题的两种方案

问题原因

你的Mock失效是因为__init__.py里导入my_func2时,my_package.my_func2模块会被提前加载。此时my_func2.py里用from my_package.my_func1 import my_func1导入的函数,会以变量形式存在于my_func2模块的命名空间中,这个变量已经绑定了原始的my_func1。后续测试中的patch如果没命中这个提前绑定的变量,就会失效。


方案一:修改业务代码的导入方式(推荐)

把my_func2.py里的直接导入改为模块级导入,这样每次调用my_func2时都会动态去原模块查找my_func1,不受提前加载的影响。

修改后的my_func2.py:

import my_package.my_func1

def my_func2():
    return my_package.my_func1.my_func1()

对应的测试代码只需要patch原始函数的路径即可:

import unittest
from unittest.mock import patch
from my_package.my_func2 import my_func2

class TestMyFunc2(unittest.TestCase):
    @patch("my_package.my_func1.my_func1")
    def test_my_func2(self, mock_my_func1):
        mock_my_func1.return_value = "MOCK DONE"
        result = my_func2()
        print(result)
        self.assertEqual(result, "MOCK DONE")

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

方案二:在测试中清除模块缓存(无需修改业务代码)

如果不能改业务代码,可以在测试方法里先删除已加载的模块缓存,重新导入my_func2,确保patch能替换到模块里的my_func1变量。

修改后的测试代码:

import unittest
import sys
from unittest.mock import patch

class TestMyFunc2(unittest.TestCase):
    @patch("my_package.my_func2.my_func1")
    def test_my_func2(self, mock_my_func1):
        # 清除my_package相关的模块缓存
        for module in list(sys.modules.keys()):
            if module.startswith("my_package"):
                del sys.modules[module]
        # 重新导入my_func2
        from my_package.my_func2 import my_func2
        
        mock_my_func1.return_value = "MOCK DONE"
        result = my_func2()
        print(result)
        self.assertEqual(result, "MOCK DONE")

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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 23:57:37