問題描述
我正在嘗試測試三個函數的調用順序.
I have three functions that I'm trying to test the call order of.
假設在模塊 module.py 我有以下內容
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)
我想檢查 b 是否在 a 之后和 c 之前被調用.因此,為 a、b 和 c 中的每一個進行模擬很容易:
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
不起作用,因為它是為每個模擬單獨維護的.
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')
這似乎可以完成工作......但是有更好的方法嗎?感覺 API 中應該已經有一些東西可以做到這一點,而我卻錯過了.
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.
推薦答案
定義一個 Mock
管理器并通過 attach_mock()
.然后檢查 mock_calls
:
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
只是為了測試它是否有效,更改 main_routine()
函數中的函數調用順序,添加查看它是否拋出 AssertionError
.
Just to test that it works, change the order of function calls in the main_routine()
function add see that it throws AssertionError
.
在 跟蹤調用順序和不那么冗長的調用斷言
希望對您有所幫助.
這篇關于檢查多個模擬的調用順序的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!