库中的patch
函数mock
对事物的导入方式很敏感。为什么我不能只使用最初定义函数的完全限定名称,而不管它是如何在其他模块中导入的,有什么深层次的原因吗?
使用“模块导入”工作正常
补丁示例.py:
# WORKS!
from mock import patch
import inner
def outer(x):
return ("outer", inner.inner(x))
@patch("inner.inner")
def test(mock_inner):
mock_inner.return_value = "MOCK"
assert outer(1) == ("outer", "MOCK")
return "SUCCESS"
if __name__ == "__main__":
print test()
内部.py:
def inner(x):
return ("inner.inner", x)
运行python patch_example.py
只是输出成功。
但是,更改导入可能会产生非常严重的后果
使用模块别名仍然有效
# WORKS!
from mock import patch
import inner as inner2
def outer(x):
return ("outer", inner2.inner(x))
@patch("inner.inner")
def test(mock_inner):
mock_inner.return_value = "MOCK"
assert outer(1) == ("outer", "MOCK")
return "SUCCESS"
if __name__ == "__main__":
print test()
但是,直接导入符号需要您更改完全限定名称。
直接导入,inner.inner
作为完全限定名称。
# FAILS!
from mock import patch
from inner import inner
def outer(x):
return ("outer", inner(x))
@patch("inner.inner")
def test(mock_inner):
mock_inner.return_value = "MOCK"
assert outer(1) == ("outer", "MOCK")
return "SUCCESS"
if __name__ == "__main__":
print test()
生产
% python patch_example.py
Traceback (most recent call last):
File "patch_example.py", line 14, in <module>
print test()
File "/usr/local/lib/python2.7/site-packages/mock/mock.py", line 1305, in patched
return func(*args, **keywargs)
File "patch_example.py", line 10, in test
assert outer(1) == ("outer", "MOCK")
AssertionError
如果我将完全限定路径更新为patch_example.inner
,补丁仍然失败。
# FAILS!
from mock import patch
from inner import inner
def outer(x):
return ("outer", inner(x))
@patch("patch_example.inner")
def test(mock_inner):
mock_inner.return_value = "MOCK"
assert outer(1) == ("outer", "MOCK")
return "SUCCESS"
if __name__ == "__main__":
print test()
% python patch_example.py
Traceback (most recent call last):
File "patch_example.py", line 14, in <module>
print test()
File "/usr/local/lib/python2.7/site-packages/mock/mock.py", line 1305, in patched
return func(*args, **keywargs)
File "patch_example.py", line 10, in test
assert outer(1) == ("outer", "MOCK")
AssertionError
不过,使用__main__.inner
我的完全限定名称修补正确的东西。
# WORKS!
from mock import patch
from inner import inner
def outer(x):
return ("outer", inner(x))
@patch("__main__.inner")
def test(mock_inner):
mock_inner.return_value = "MOCK"
assert outer(1) == ("outer", "MOCK")
return "SUCCESS"
if __name__ == "__main__":
print test()
打印“成功”
那么,为什么当from inner import inner
使用原始符号的完全限定名称inner.inner
或使用主 python 模块的名称而不是使用 inner 导入时,我不能修补它的值__name__
?
在 OS X 上使用 Python 2.7.12 测试。