假设一个项目中有两个包:some_package
and another_package
.
# some_package/foo.py:
def bar():
print('hello')
# another_package/function.py
from some_package.foo import bar
def call_bar():
# ... code ...
bar()
# ... code ...
我想测试another_package.function.call_bar
嘲笑some_package.foo.bar
因为它有一些我想避免的网络 I/O。
这是一个测试:
# tests/test_bar.py
from another_package.function import call_bar
def test_bar(monkeypatch):
monkeypatch.setattr('some_package.foo.bar', lambda: print('patched'))
call_bar()
assert True
令我惊讶的是它输出hello
代替patched
。我尝试调试这个东西,在测试中放置一个 IPDB 断点。当我手动导入时some_package.foo.bar
断点后并调用bar()
I get patched
.
在我的真实项目中,情况更加有趣。如果我在项目根目录中调用 pytest 我的函数不会被修补,但是当我指定tests/test_bar.py
作为一个论点-它有效。
据我了解,这与from some_package.foo import bar
陈述。如果它在猴子补丁发生之前执行,那么补丁会失败。但在上面示例的压缩测试设置中,修补在这两种情况下都不起作用。
为什么在 IPDB REPL 中遇到断点后它还能工作?
While 罗尼的回答 https://stackoverflow.com/a/31746577/1953800它会迫使您更改应用程序代码。一般来说,您不应该为了测试而这样做。
相反,您可以显式修补第二个包中的对象。这在单元测试模块的文档 https://docs.python.org/dev/library/unittest.mock.html#where-to-patch.
monkeypatch.setattr('another_package.bar', lambda: print('patched'))
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)