检查多个模拟中的呼叫顺序 [英] Checking call order across multiple mocks

查看:87
本文介绍了检查多个模拟中的呼叫顺序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



假设在模块module.py中,我有以下几个

 #module.py 

def a(* args):
#做第一件事

def b(* args):
#做第二件事

def c(* args):
#做第三件事

$ b $ def main_routine():
a_args =('a')
b_args =('b')
c_args =('c')

a(* a_args)
b(* b_args)
c(* c_args)

我想检查b在a之后和c之前被调用。因此,为a,b和c中的每一个获取模拟都很简单:

 #tests.py 

@ mock.patch('module.a')
@ mock.patch('module.b')
@ mock.patch('module.c')
def test_main_routine(c_mock ,b_mock,a_mock):
#在这里测试所有的东西

检查每一个个人嘲笑也很容易。我如何查看相互之间的通话顺序?



call_args_list 不会起作用,因为它是针对每个模拟单独维护的。

我尝试过使用副作用来记录每个调用:

  calls = [] 
def register_call(* args):
calls.append(mock.call(* args))
return mock.DEFAULT

a_mock.side_effect = register_call
b_mock.side_effect = register_call
c_mock.side_effect = register_call

但这只给我指出这些嘲弄是被调用的,但不是该调用的实际模拟。我可以添加更多的逻辑:

 #tests.py从functools导入
导入部分

def register_call(* args,** kwargs):
calls.append(kwargs.pop('caller',None),mock.call(* args,** kwargs))
return mock .DEFAULT

a_mock.side_effect = partial(register_call,caller ='a')
b_mock.side_effect = partial(register_call,caller ='b')
c_mock.side_effect = partial(register_call,caller ='c')

这似乎完成了工作......有没有更好的方法?它感觉应该已经有API中的东西,可以做到这一点,我很想念。

解决方案

定义一个 Mock 管理器,并通过 attach_mock() 。然后检查 mock_calls

  @patch('module.a ')
@patch('module.b')
@patch('module.c')
def test_main_routine(c,b,a):
manager = Mock )
manager.attach_mock(a,'a')
manager.attach_mock(b,'b')
manager.attach_mock(c,'c')

module.main_routine()

expected_calls = [call.a('a'),call.b('b'),call.c('c')]
assert manager .mock_calls == expected_calls

为了测试它的工作原理,改变函数调用的顺序, code> main_routine() function add看到它抛出 AssertionError



跟踪查看更多示例订单的调用和较少的详细调用断言



希望有帮助。


I have three functions that I'm trying to test the call order of.

Let's say that in module module.py I have the following

# module.py    

def a(*args):
    # do the first thing

def b(*args):
    # do a second thing

def c(*args):
    # do a third thing


def main_routine():
    a_args = ('a')
    b_args = ('b')
    c_args = ('c')

    a(*a_args)
    b(*b_args)
    c(*c_args)

I want to check that b is called after a, and before c. So getting a mock for each of a, b and c is easy:

# tests.py

@mock.patch('module.a')
@mock.patch('module.b')
@mock.patch('module.c')
def test_main_routine(c_mock, b_mock, a_mock):
    # test all the things here

Checking that each of the individial mocks are called is easy, too. How do I check the order of the calls relative to one another?

call_args_list won't work as it's maintained separately for each mock.

I've tried using a side effect to log each of the calls:

calls = []
def register_call(*args):
    calls.append(mock.call(*args))
    return mock.DEFAULT

a_mock.side_effect = register_call
b_mock.side_effect = register_call
c_mock.side_effect = register_call

But this only gives me the args that the mocks were called with, but not the actual mock that the call was made against. I can add a bit more logic:

# tests.py
from functools import partial

def register_call(*args, **kwargs):
    calls.append(kwargs.pop('caller', None), mock.call(*args, **kwargs))
    return mock.DEFAULT

a_mock.side_effect = partial(register_call, caller='a')
b_mock.side_effect = partial(register_call, caller='b')
c_mock.side_effect = partial(register_call, caller='c')

And that seems to get the job done... Is there a better way though? It feels like there should already be something in the API that can do this that I'm missing.

解决方案

Define a Mock manager and attach mocks to it via attach_mock(). Then check for the mock_calls:

@patch('module.a')
@patch('module.b')
@patch('module.c')
def test_main_routine(c, b, a):
    manager = Mock()
    manager.attach_mock(a, 'a')
    manager.attach_mock(b, 'b')
    manager.attach_mock(c, 'c')

    module.main_routine()

    expected_calls = [call.a('a'), call.b('b'), call.c('c')]
    assert manager.mock_calls == expected_calls

Just to test that it works, change the order of function calls in the main_routine() function add see that it throws AssertionError.

See more examples at Tracking order of calls and less verbose call assertions

Hope that helps.

这篇关于检查多个模拟中的呼叫顺序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆