【问题标题】:How to assert method call order with Python Mock?如何使用 Python Mock 断言方法调用顺序?
【发布时间】:2015-09-08 16:59:21
【问题描述】:

假设我有一个 python 函数

def func(self):
    self.method_1()
    self.method_2()

如何编写可以断言 method_1 在 method_2 之前被调用的单元测试?

@mock.patch(method_1)
@mock.patch(method_2)
def test_call_order(method_2_mock, method_1_mock):
     # Test the order

【问题讨论】:

标签: python mocking


【解决方案1】:

您的情况与Python Unit Testing with two mock objects, how to verify call-order? 略有不同。你应该做的是将method_2_mockmethod_1_mock 设置为一个新的模拟对象的子对象,然后请求mock_calls 属性或使用assert_has_calls

@mock.patch(method_1)
@mock.patch(method_2)
def test_call_order(method_2_mock, method_1_mock):
    mock_parent = Mock()
    mock_parent.m1, mock_parent.m2 = method_1_mock, method_2_mock
    <test code>
    """Check if method 1 is called before method 2"""
    mock_parent.assert_has_calls([call.m1(), call.m2()])

这段代码中省略了很多细节,比如调用参数。看看call 和非常有用的ANY 助手。

注意 这仅对 python3 中的unitetest.mock 有效。对于 python 2.7 和 mock 1.0.1,您应该改用 attach_mock

【讨论】:

    【解决方案2】:

    另一种选择是创建一个简单的列表并通过side_effect 将每个模拟附加到它。

    @mock.patch(method_1)
    @mock.patch(method_2)
    def test_call_order(method_2_mock, method_1_mock):
        call_order = []
        method_1_mock.side_effect = lambda *a, **kw: call_order.append(method_1_mock)
        method_2_mock.side_effect = lambda *a, **kw: call_order.append(method_2_mock)
        # Run test code...
        assert call_order == [method_1_mock, method_2_mock]
    

    每次调用该方法时,都会调用side_effect lambda 函数。由于列表是有序的,因此这是一种检查方法调用顺序的干净方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-12-08
      • 2012-08-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-22
      • 2017-03-01
      • 1970-01-01
      相关资源
      最近更新 更多