2017-09-15 142 views
0

方法我已經有了一個真正有用的蟒蛇方法是這樣的:如何嘲笑非呼叫反對在Python單元測試庫

def stop_widget(): 
    original_widget = load_widget_from_file() 
    if original_widget: 
    original_widget.close() 
當我想測試它以

確保我叫close(),我做:

@patch('load_widget_from_file') 
def test_stop_widget_with_original_widget(self, lwff_mock): 
    mock_widget = create_autospec(Widget) 
    lwff_mock.return_value = mock_widget 
    stop_widget() 
    mock_widget.close.assert_called_once_with() 

,但我該怎麼辦時,我想測試調用closeload_widget_from_file返回值不計算爲真?

如果我試圖使另一個單元測試有:

@patch('load_widget_from_file') 
def test_stop_widget_with_original_widget(self, lwff_mock): 
    mock_widget = None 
    lwff_mock.return_value = mock_widget 
    stop_widget() 
    mock_widget.close.assert_not_called() 

這將炸燬。

+0

'assert_not_called'怎麼樣? – larsks

+0

@larsks,我沒有一個實例化一個函數來調用它的對象。 –

+0

如果您在第二種方法中執行'mock_widget = create_autospec(Widget)',會發生什麼情況,就像在第一種方法中一樣? –

回答

1

您需要創建第二個模擬對象(而不是設置mock_widget = None),但小部件需要是falsey以防止函數進入if條件。

在Python,對象始終是「truthy」,除非有一個零長度,或它具有__bool__ method that returns False

對象.__布爾__(個體)

調用,以實現真值測試和內置操作bool();應該返回FalseTrue。如果未定義此方法,則調用__len__()(如果已定義),並且如果該對象的結果非零,則該對象被視爲真。如果一個類既沒有定義__len__()也沒有定義__bool__(),它的所有實例都被認爲是真實的。

大概是「正確的方式」到__bool__方法添加到您的模擬對象將use MagicMock,它附帶了很多的Python的「魔術方法」預先定義的。但你也必須將返回值更改爲False,如下所示:

@patch('load_widget_from_file') 
def test_stop_widget_with_original_widget(self, lwff_mock): 
    mock_widget = MagicMock() 
    mock_widget.__bool__.return_value = False 
    lwff_mock.return_value = mock_widget 
    stop_widget() 
    mock_widget.close.assert_not_called() 
+1

是的,第一種方式不起作用 - __bool__未在原始類中定義, (至少不是我正在運行Python 3.5.1的版本,我查看了unittest框架的一些更新日誌,看起來像很久以前某人爲__bool__實現了一些magic方法,但我沒有看到它的文檔 –

+0

第二種方式就像冠軍一樣,謝謝! –

+0

是的,我沒有打擾測試。刪除了第一個想法 - 不知道爲什麼它不工作,但不管。 –