我有一个非常有用的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()
但如果close
的返回值未评估为True,我想测试不调用load_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 :(得分:1)
您需要创建第二个模拟对象(而不是设置mock_widget = None
),但是窗口小部件必须是假的,以防止函数进入if条件。
在Python中,一个对象总是“真实的”,除非它具有零长度,或者它具有__bool__
method that returns False
:
对象.__布尔__(个体)
被要求实施真值测试和内置操作
bool()
;应该返回False
或True
。如果未定义此方法,则调用__len__()
(如果已定义),如果对象的结果非零,则认为该对象为true。如果某个类既未定义__len__()
也未定义__bool__()
,则其所有实例都被视为true。
向模拟对象添加__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()