Python unittest中patch类外普通函数失败的问题求助
问题排查与解决
问题根源
unittest.mock.patch的核心逻辑是替换指定模块路径下的对象引用,而非修改已经导入到当前模块的本地引用:
- 在
test_bad里,你已经把func2直接导入到test_a.py的本地命名空间,此时test_a里的func2是原函数的一个独立引用。你patch的是code.a.func2,但实际调用的是本地的func2,自然不会触发mock效果。 - 类方法能正常工作是因为:调用
a_obj.func()时,是从A类的实例上获取方法,而A类始终指向code.a模块里的类定义,patchcode.a.A.func后,类的方法被替换,实例调用时自然用的是mock后的版本。
解决方法
有两种可靠的修复方式:
方式1:通过原模块调用函数
不要直接导入func2,而是导入整个code.a模块,通过模块调用函数,确保使用的是被patch后的引用:
修改test_a.py:
from unittest.mock import patch import code.a from code.a import A def test_good(): with patch('code.a.A.func'): a_obj = A() a_obj.func() def test_bad_fixed(): with patch('code.a.func2'): code.a.func2()
方式2:patch当前模块的本地引用
直接patchtest_a模块里的func2本地引用:
修改test_a.py:
from unittest.mock import patch from code.a import A, func2 def test_good(): with patch('code.a.A.func'): a_obj = A() a_obj.func() def test_bad_fixed(): # 如果用python -m pytest运行,建议用完整模块路径'code.test_a.func2' with patch('__main__.func2'): func2()
关键总结
使用patch时,必须保证patch的路径是代码实际调用该对象的位置:
- 若代码通过原模块调用对象,就patch原模块路径;
- 若代码用本地导入的引用调用,就patch当前模块里的本地引用路径。
内容的提问来源于stack exchange,提问作者Matmozaur
相关产品推荐
相关产品推荐

