如何使用Python Mock断言方法调用顺序?

时间:2015-09-08 16:59:21

标签: python mocking

假设我有一个python函数

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

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

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

2 个答案:

答案 0 :(得分:8)

您的案例与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代替。

答案 1 :(得分:0)

另一种选择是创建一个简单的列表并通过 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 函数。由于列表是有序的,因此这是一种检查方法调用顺序的简洁方法。