为何模块中用from关键字导入函数后,单元测试无法正确Mock该函数?
问题原因解析
核心原因是Python的导入机制和命名空间特性导致的:
两种导入方式的本质区别
当
a.py用import b时,bar()里调用的b.foo()是每次都去b模块的命名空间中查找foo对象。这时候你用mock.patch('b.foo')替换的是b模块里的foo引用,bar()调用时自然会拿到被mock后的对象,测试就能正常通过。但改成
from b import foo后,Python会把b模块里的foo函数对象复制一份到a模块自己的命名空间里。这时候a模块的命名空间里就有了一个独立的foo引用,指向原始的b.foo函数。后续你用mock.patch('b.foo')只是修改了b模块里的foo指向,但a模块里的foo引用完全不受影响,bar()调用的还是a自己命名空间里的原始foo,所以mock失效。
解决办法
要让mock生效,你需要替换的是**a模块命名空间里的foo引用**,也就是把mock的目标改成'a.foo':
修改后的test_a.py代码:
from a import bar from unittest import mock def test_bar(): with mock.patch('a.foo') as mock_foo: bar() mock_foo.assert_called_once()
这样运行测试,就能正确捕获到bar()对foo的调用了。
内容的提问来源于stack exchange,提问作者scdmb
相关产品推荐
相关产品推荐

