2013-10-24 61 views
1

我正在重構現有代碼以使用blinker庫而不是傳遞迴調函數。我有一大堆現有的測試,它們利用模擬來檢查回調是否正確觸發。但是,當我嘗試對使用blinker的新代碼運行測試時,我從Mock中得到一個異常。將模擬信號傳遞給blinker signal.connect()會引發「AttributeError:__name__」

該異常可以很容易地在repl上覆制,並且歸因於blinker試圖訪問模擬的__name__屬性。

>>> from mock import Mock 
>>> from blinker import signal 
>>> 
>>> test = signal('test') 
>>> m = Mock() 
>>> 
>>> test.connect(m) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/Users/ed/.virtualenvs/iws/lib/python2.7/site-packages/blinker/base.py", line 113, in connect 
     receiver_ref = reference(receiver, self._cleanup_receiver) 
    File "/Users/ed/.virtualenvs/iws/lib/python2.7/site-packages/blinker/_utilities.py", line 124, in reference 
     weak = callable_reference(object, callback) 
    File "/Users/ed/.virtualenvs/iws/lib/python2.7/site-packages/blinker/_utilities.py", line 135, in callable_reference 
     return BoundMethodWeakref(target=object, on_delete=callback) 
    File "/Users/ed/.virtualenvs/iws/lib/python2.7/site-packages/blinker/_saferef.py", line 143, in __new__ 
     base.__init__(target, on_delete, *arguments, **named) 
    File "/Users/ed/.virtualenvs/iws/lib/python2.7/site-packages/blinker/_saferef.py", line 188, in __init__ 
     self.func_name = str(im_func.__name__) 
    File "/Users/ed/.virtualenvs/iws/lib/python2.7/site-packages/mock.py", line 702, in __getattr__ 
     raise AttributeError(name) 

MagicMock引發相同的異常。

我一直無法弄清楚如何準備模擬,以避免引發異常。我可以用虛擬函數替換模擬並在其中編寫測試,但我有超過1000個測試。

+0

你能張貼'connect'的代碼?在某些時候,你的模擬對象的某個屬性的某個屬性應該是一個函數對象,它具有一個'im_func'屬性。你必須正確地配置你的模擬器,以便它能夠與你的代碼一起工作。 – chepner

回答

2

我已經找到了解決辦法:

創建一個虛擬函數並傳遞,爲模擬作爲規範成功。

>>> from blinker import signal 
>>> from mock import Mock 
>>> 
>>> def foo(): 
...  pass 
... 
>>> t = signal('test') 
>>> m = Mock(spec=foo) 
>>> m.__name__ 
<Mock name='mock.__name__' id='4471403152'> 
>>> t.connect(m) 
<Mock spec='function' id='4471883984'> 
>>> t.send() 
[(<Mock spec='function' id='4471883984'>, <Mock name='mock()' id='4471404624'>)] 
>>> m.called 
True 
+0

這對我不起作用,當我調用t.connect(m)時,得到「TypeError:無法連接'str'和'模擬'對象」。我使用blinker 1.3和模擬1.0.0。 – NeilenMarais

+0

我正在使用模擬0.8.0和blinker 1.3 - 哪些工作 - 我會快速看看模擬1.0.0 – ejrowley

+0

剛剛測試與模擬版本1.0.1和示例代碼工程 – ejrowley

0

速記

from mock import MagicMock  
mock_signal = MagicMock(spec={})