断言对模拟方法的连续调用

2024-05-29 06:00:07 发布

您现在位置:Python中文网/ 问答频道 /正文

Mock有一个helpful ^{} method。然而,据我所知,这只检查对方法的最后一次调用 如果我的代码连续3次调用mocked方法,每次都使用不同的参数,我如何用它们的特定参数断言这3个调用?


Tags: 方法代码参数断言mockmethodhelpfulmocked
3条回答

assert_has_calls是解决这个问题的另一种方法。

从文档中:

assert_has_calls(calls, any_order=False)

assert the mock has been called with the specified calls. The mock_calls list is checked for the calls.

If any_order is False (the default) then the calls must be sequential. There can be extra calls before or after the specified calls.

If any_order is True then the calls can be in any order, but they must all appear in mock_calls.

示例:

>>> from mock import call, Mock
>>> mock = Mock(return_value=None)
>>> mock(1)
>>> mock(2)
>>> mock(3)
>>> mock(4)
>>> calls = [call(2), call(3)]
>>> mock.assert_has_calls(calls)
>>> calls = [call(4), call(2), call(3)]
>>> mock.assert_has_calls(calls, any_order=True)

来源:https://docs.python.org/3/library/unittest.mock.html#unittest.mock.Mock.assert_has_calls

可以使用^{} attribute将参数与以前的方法调用进行比较。与^{} attribute一起使用应该可以让您完全控制。

通常,我不在乎电话的先后顺序,只关心电话的发生。在这种情况下,我将^{}与关于^{}的断言结合起来。

>>> import mock
>>> m = mock.Mock()
>>> m(1)
<Mock name='mock()' id='37578160'>
>>> m(2)
<Mock name='mock()' id='37578160'>
>>> m(3)
<Mock name='mock()' id='37578160'>
>>> m.assert_any_call(1)
>>> m.assert_any_call(2)
>>> m.assert_any_call(3)
>>> assert 3 == m.call_count
>>> m.assert_any_call(4)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "[python path]\lib\site-packages\mock.py", line 891, in assert_any_call
    '%s call not found' % expected_string
AssertionError: mock(4) call not found

我发现这样做比将大量调用传递到单个方法中更容易阅读和理解。

如果您真的关心顺序或期望多个相同的调用,^{}可能更合适。

编辑

自从我发布了这个答案,我重新思考了我的测试方法。我认为值得一提的是,如果你的测试变得如此复杂,你可能是测试不当或有设计问题。mock是为测试面向对象设计中的对象间通信而设计的。如果您的设计不是面向对象的(如在更多的过程或功能中),那么模拟可能是完全不合适的。您可能在方法内部有太多的事情要做,或者您可能正在测试最好不要锁定的内部细节。当我的代码不是很面向对象的时候,我开发了这个方法中提到的策略,我相信我也在测试内部细节,最好不要修改。

相关问题 更多 >

    热门问题