У меня есть три функции, которые я пытаюсь проверить порядок вызовов.
Скажем, что в модуле module.py у меня есть следующее
# 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)
Я хочу проверить, что b вызывается после a и до c. Так что получить макет для каждого из, 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):
# test all the things here
Проверка того, что каждый из них называется так же просто, тоже. Как проверить порядок вызовов относительно друг друга?
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
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')
И это похоже на то, чтобы сделать работу... Есть ли лучший способ? Похоже, что в API уже должно быть что-то, что может сделать это, что мне не хватает.