在doctest中模拟(from X import Y)的Y(python)
我正在尝试创建一个文档测试,里面需要模拟一个在另一个模块中的函数,这个函数是通过下面的方式导入的。
from foomodule import foo
def bar():
"""
>>> from minimock import mock
>>> mock('foo', nsdicts=(bar.func_globals,), returns=5)
>>> bar()
Called foo()
10
"""
return foo() * 2
import doctest
doctest.testmod()
foomodule.py:
def foo():
raise ValueError, "Don't call me during testing!"
这样做会失败。
如果我把导入改成import foomodule,然后到处使用foomodule.foo,这样就能正常工作了。
但是,有没有什么办法可以模拟以刚才那种方式导入的函数呢?
2 个回答
5
你刚刚遇到了一个很重要的原因,这就是为什么最好不要从模块内部导入对象,而是只从模块本身导入(可能是从包里面)。我们在谷歌的风格指南中把这个规则写进去了(可以在这里找到),我强烈推荐每位Python程序员都遵循这个规则。
话虽如此,你需要做的是把你刚刚用模拟对象替换掉的foomodule.foo放回当前模块。我对doctest的内部机制记得不太清楚,不能确认
>>> import foomodule
>>> foo = foomodule.foo
是否足够用——试试看,如果不行,那就用
>>> import foomodule
>>> import sys
>>> sys.modules[__name__].foo = foomodule.foo
是的,这看起来有点乱,但造成这种混乱的原因就是那条看似无害的from foomodule import foo
——避免使用它,你的生活会简单很多,工作效率也会提高;-).
2
最后,发现这个问题其实是因为MiniMock的主版本出了问题。旧的稳定版本运行得很正常。