检查多个模拟中的呼叫顺序 [英] Checking call order across multiple mocks
问题描述
假设在模块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屋!