简体   繁体   English

如何在Python unittest库中模拟对对象方法的非调用

[英]How to mock non-calls to object methods in Python unittest library

I've got a really useful python method like this: 我有一个非常有用的python方法,如下所示:

def stop_widget():
  original_widget = load_widget_from_file()
  if original_widget: 
    original_widget.close()

when I want to test it to make sure I called close() , I do: 当我想对其进行测试以确保我调用了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()

but what do I do when I want to test not calling close when the return value of load_widget_from_file doesn't evaluate to True? 但是当load_widget_from_file的返回值未评估为True时,我想测试调用close怎么办?

If I tried making another unit test with: 如果我尝试使用以下方法进行另一个单元测试:

@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()

this would blow up. 这会炸毁。

You need to create a second mock object (instead of setting mock_widget = None ), but the widget needs to be falsey to prevent the function from entering the if condition. 您需要创建第二个模拟对象(而不是设置嘲笑对象mock_widget = None ),但是该小部件必须为false,以防止该函数输入if条件。

In Python, an object is always "truthy" unless is has a zero-length, or it has a __bool__ method that returns False : 在Python中,除非对象的长度为零或具有返回False__bool__方法,否则对象始终是“真实的”:

object.__bool__(self) 对象.__布尔__(个体)

Called to implement truth value testing and the built-in operation bool() ; 调用以实现真值测试和内置操作bool() should return False or True . 应该返回FalseTrue When this method is not defined, __len__() is called, if it is defined, and the object is considered true if its result is nonzero. 如果未定义此方法,则调用__len__() (如果已定义),并且如果其结果为非零,则认为该对象为true。 If a class defines neither __len__() nor __bool__() , all its instances are considered true. 如果一个类__len__()__bool__() ,则其所有实例均被视为true。

Probably the "right way" to add a __bool__ method to your mock object would be to use MagicMock , which comes with many of the Python "magic methods" pre-defined. 向您的模拟对象添加__bool__方法的“正确方法”可能是使用MagicMock ,它附带了许多预定义的Python“魔术方法”。 But you'll also have to change the return value to False , like so: 但是您还必须将返回值更改为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()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM