2015-08-17 67 views
3

我試圖嘲笑一個協程。因此,這個模擬的__next__()close()被調用。雖然嘲諷close()作品,我不能嘲笑__next__()如何模擬對__next__的呼叫

mock_coroutine = mock.Mock() 
    mock_coroutine.some_call(1, 2, 3) 
    mock_coroutine.some_call.assert_called_with(1, 2, 3) 
    mock_coroutine.close() 
    mock_coroutine.close.assert_called_with() 
    #this fails 
    mock_coroutine.__next__() 
    mock_coroutine.__next__.assert_called_with() 

我缺少什麼?如何確保我的模擬的__next__()方法被調用?

現在,我使用了以下內容:

class MockCoroutine: 
    def __next__(self): 
     self.called_next = True 

    def close(self): 
     self.called_exit = True 

但是,我非常喜歡使用一個標準的模擬。

回答

4

您需要使用MagicMock,不Mock,在默認情況下有魔術方法類似__next__可供選擇:

>>> from unittest import mock 
>>> mock_coroutine = mock.MagicMock() 
>>> mock_coroutine.__next__() 
<MagicMock name='mock.__next__()' id='4464126552'> 
>>> mock_coroutine.__next__.assert_called_with() 

the documentation報價:

Mock允許您指定函數(或其他Mock實例)魔術方法,他們將被適當調用。 MagicMock類只是一個Mock變體,它具有爲您預先創建的所有魔術方法(無論如何,所有有用的方法)。

所以,或者,你仍然可以使用常規Mock對象,但你需要明確地添加屬性:

>>> mock_coroutine = mock.Mock() 
>>> mock_coroutine.__next__ = mock.Mock() 
>>> mock_coroutine.__next__() 
<Mock name='mock.__next__()' id='4464139232'> 

這是因爲雖然Mock在您訪問他們創建的飛行特性,具有前導和尾隨下劃線的任何屬性都被明確地豁免。見this footnote

唯一的例外是神奇的方法和屬性(那些具有前導和尾隨雙下劃線)。模擬不會創建這些,而是​​會產生一個AttributeError。這是因爲解釋器通常會隱式地請求這些方法,並且在需要一個魔術方法時會很困惑地獲得一個新的Mock對象。如果您需要神奇的方法支持,請參閱magic methods

但要注意的魔術方法通常指的類,而不是實例,所以直接添加__next__屬性爲Mock實例仍然可能無法進行查找; MagicMock班會爲您解決這個特定問題。

+0

這工作。坦克很多! – AlexC