@patch
在2.7和3.6下似乎不会产生相同的行为。
这是我的项目结构:
project/
foo.py
bar.py
lol.py
tests/
test_project.py
foo.py:
class Foo:
pass
bar.py(导入Foo):
from project.foo import Foo
class Bar:
def __init__(self):
f = Foo()
lol.py(导入栏):
from bar import Bar
class Lol:
def __init__(self):
b = Bar()
由于bar.py
使用from project.foo import Foo
导入了Foo,因此我正在修补bar.Foo
(根据where to patch文档):
test_bar.py:
from project import lol
from project import bar
@patch('bar.Foo') # Works in 3.6, fails with 2.7
def test_lol(mock_Foo):
l = lol.Lol()
mock_Foo.assert_called()
此设置可在Python 3.6中正确运行,但在2.7中将失败(Foo无法得到修补)。
但是,如果我将设置切换为:
test_bar.py:
from project import lol
# from project import bar # No need to import bar anymore
@patch('project.bar.Foo') # Works in 2.7, fails with 3.6
def test_lol(mock_Foo):
l = lol.Lol()
mock_Foo.assert_called()
它在2.7中有效,但在3.6中不可用。
使用@patch
使其在python版本之间产生一致的结果的推荐方法是什么?
注意:此问题仅在我测试lol.py
时出现。如果我从单元测试中调用bar.py
,则使用第二个设置@patch('cookie_test.bar.Foo')
可以获得一致的结果,并且它在2.7和3.6中都可以使用。
答案 0 :(得分:1)
将__init__.py
文件添加到您的project
目录,并更改Bar
中lol.py
的导入后,我无法使用2.7和3.6复制差异:
from project.bar import Bar
无论哪种情况,您都不需要在测试中导入bar
-模拟程序通过解析传递给bar
装饰器的字符串来查找mock
。
我怀疑您看到的错误是由于Python 3使用绝对导入(https://www.python.org/dev/peps/pep-0328/)