在Python中使用/ import语句进行模拟修补

one*_*elf 24 python python-mock

我试图让mock.patch处理以下示例代码:

from mock import patch
from collections import defaultdict

with patch('collections.defaultdict'):
  d = defaultdict()
  print 'd:', d
Run Code Online (Sandbox Code Playgroud)

这输出如下:

d: defaultdict(None, {})
Run Code Online (Sandbox Code Playgroud)

这意味着defaultdict没有修补.

如果我用直接导入语句替换from/import语句,它可以工作:

from mock import patch
import collections

with patch('collections.defaultdict'):
 d = collections.defaultdict()
 print 'd:', d
Run Code Online (Sandbox Code Playgroud)

输出是:

d: <MagicMock name='defaultdict()' id='139953944084176'>
Run Code Online (Sandbox Code Playgroud)

有没有办法使用from/import修补呼叫?

谢谢

Ada*_*ner 39

如果您在同一模块中修补某些内容,则可以使用__main__:

from mock import patch
from collections import defaultdict

with patch('__main__.defaultdict'):
    d = defaultdict()
    print 'd:', d
Run Code Online (Sandbox Code Playgroud)

但是,如果您要为导入的模块进行模拟,则需要使用该模块的名称,以便修补正确的引用(或名称):

# 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()
Run Code Online (Sandbox Code Playgroud)

这里的要点是补丁需要完整的路径来修补它.当在当前模块中修补某些内容时,这看起来有点奇怪,因为人们不经常使用__main__(或者必须参考当前模块).


Bre*_*arn 10

patch通过修补名称来工作.collections.defaultdict如果使用名称defaultdict(在本地命名空间中)访问该对象,则无法通过修补名称来实现任何目的.请参阅http://www.voidspace.org.uk/python/mock/patch.html#id1上的文档.

  • 这是否意味着如果你改变你是否使用`from X import Y`或`import XY`的实现细节,你的单元测试会默默地开始表现得非常不同? (7认同)