2017-09-15 113 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

是的,我没有打扰测试。删除了第一个想法 - 不知道为什么它不工作,但不管。 –