[英]Mock patching from/import statement in Python
I am trying to get mock.patch to work on the following piece of sample code: 我试图让mock.patch处理以下示例代码:
from mock import patch
from collections import defaultdict
with patch('collections.defaultdict'):
d = defaultdict()
print 'd:', d
This outputs the following: 这输出如下:
d: defaultdict(None, {})
Which means that defaultdict was not patched. 这意味着defaultdict没有修补。
If I replace the from/import statement with a straight import statement it works: 如果我用直接导入语句替换from / import语句,它可以工作:
from mock import patch
import collections
with patch('collections.defaultdict'):
d = collections.defaultdict()
print 'd:', d
Output is: 输出是:
d: <MagicMock name='defaultdict()' id='139953944084176'>
Is there any way to patch a call using from/import? 有没有办法使用from / import修补呼叫?
Thank you 谢谢
If you're patching something in the same module, you can use __main__
: 如果您在同一模块中修补某些内容,则可以使用
__main__
:
from mock import patch
from collections import defaultdict
with patch('__main__.defaultdict'):
d = defaultdict()
print 'd:', d
If you're mocking something for an imported module, however, you'll want to use that module's name so the correct reference (or name) is patched: 但是,如果您要为导入的模块进行模拟,则需要使用该模块的名称,以便修补正确的引用(或名称):
# foo.py
from collections import defaultdict
def bar():
return defaultdict()
# foo_test.py
from mock import patch
from foo import bar
with patch('foo.defaultdict'):
print bar()
The point here is that patch wants the full path to the thing it is patching. 这里的要点是补丁需要完整的路径来修补它。 This just looks a little weird when patching something in the current module, since folks don't often use
__main__
(or have to refer to the current module, for that matter). 当在当前模块中修补某些内容时,这看起来有点奇怪,因为人们不经常使用
__main__
(或者必须引用当前模块)。
patch
works by patching names . patch
通过修补名称来工作 。 You can't achieve anything by patching the name collections.defaultdict
if you are using the name defaultdict
(in the local namespace) to access the object. 如果使用名称
defaultdict
(在本地命名空间中)来访问对象,则无法通过修改名称collections.defaultdict
来实现任何目的。 See the documentation at http://www.voidspace.org.uk/python/mock/patch.html#id1 . 请参阅http://www.voidspace.org.uk/python/mock/patch.html#id1上的文档。
The names can be very confusing in this case. 在这种情况下,名称可能非常混乱。 We always want to mock a class definition in a namespace.
我们总是希望在命名空间中模拟类定义。 The namespace is the module in which the import takes place.
命名空间是导入发生的模块。 The class definition is the name used in that namespace.
类定义是该命名空间中使用的名称。
Let's take a concrete example: 我们来看一个具体的例子:
from myproj.utilities import Actor
from myproj.utilities import Actor
class Actor:
def __init__(name):
self.name = name
from myproj.utilities import Actor
class App:
def __init__(name):
self.actor = Actor(name)
from mock import patch
from myproj.application import App
test:
# format: patch('<namespace>.<Class>')
# the namespace in which we with to mock
# the class definition we wish to mock
with patch('myproj.application.Actor'):
app = App('Someone')
print( type(app.actor) ) # expect a MagicMock
I tried several other approaches and this one works well for me. 我尝试了其他几种方法,这个方法对我很有用。 I have not tests the code above but instead generalized it from my own specific case.
我没有测试上面的代码,而是从我自己的特定情况推广它。 So, it might be a little off.
所以,它可能有点偏。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.