从模拟补丁/ Python中

问题描述:

我试图让mock.patch对下面的一段示例代码import语句:从模拟补丁/ Python中

from mock import patch 
from collections import defaultdict 

with patch('collections.defaultdict'): 
    d = defaultdict() 
    print 'd:', d 

此输出以下:

d: defaultdict(None, {}) 

这意味着该defaultdict未修补。

如果我采用了直板import语句它的工作原理更换从/ import语句:

from mock import patch 
import collections 

with patch('collections.defaultdict'): 
d = collections.defaultdict() 
print 'd:', d 

输出是:

d: <MagicMock name='defaultdict()' id='139953944084176'> 

有什么办法来修补从/导入使用电话吗?

谢谢

如果你在同一模块中修补的东西,你可以用__main__

from mock import patch 
from collections import defaultdict 

with patch('__main__.defaultdict'): 
    d = defaultdict() 
    print 'd:', d 

如果你嘲笑的东西导入模块,不过,你会想使用该模块的名称,以便正确引用(或名称)进行了修补:

# 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() 

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

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

+3

这是否意味着你的单元测试会悄悄地开始,如果你改变你是否使用了实现的细节表现非常,非常不同的'从X进口Y'或'进口X.Y'? – detly 2013-12-22 13:34:05

+0

@detly:我相信这是事实,尽管我对模拟不是很熟悉,所以我不能从经验中说出。 – BrenBarn 2013-12-22 17:50:32

+0

@ detly是的,这是正确的 – Daenyth 2016-04-08 18:19:23