2012-07-05 145 views
16

我試圖讓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'> 

有什麼辦法來修補從/導入使用電話嗎?

謝謝

回答

21

如果你在同一模塊中修補的東西,你可以用__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__(或者必須參考當前模塊)。

7

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