我想测试函数的默认行为。我有以下内容:
# app/foo.py
DEFAULT_VALUE = 'hello'
def bar(text=DEFAULT_VALUE):
print(text)
# test/test_app.py
import app
def test_app(monkeypatch):
monkeypatch.setattr('app.foo.DEFAULT_VALUE', 'patched')
app.foo.bar()
assert 0
输出是hello
;不是我想要的。
一种解决方案是显式传递默认值:app.foo.bar(text=app.foo.DEFAULT_VALUE)
.
但我发现有趣的是,当默认为全局范围时,这似乎不是问题:
# app/foo.py
DEFAULT_VALUE = 'hello'
def bar():
print(DEFAULT_VALUE)
输出是patched
.
为什么会发生这种情况?还有比显式传递默认值更好的解决方案吗?
函数默认值绑定在函数定义时间.
当您进入测试代码时,定义该函数的模块已经被导入,并且通过在模块级别常量上进行猴子修补来交换默认值已经太晚了。这个名字已经被解决了。
解决方法是像这样定义函数:
def bar(text=None):
if text is None:
text = DEFAULT_VALUE
print(text)
现在在函数中查找默认值call时间,这意味着模块级别默认的猴子补丁仍然可以工作。
如果您不喜欢修改函数定义,那么您可以对函数对象本身进行 Monkeypatch:
monkeypatch.setattr("app.foo.bar.__defaults__", ("test_hello",))
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)