[英]Checking whether function has been called multiple times with different parameters
Assume we have a function f(x,y)
and another function 假设我们有一个函数
f(x,y)
和另一个函数
def g():
# ...
f(i,j) # i,j vary and f is called multiple times
# ...
We want to write a Unit test that checks whether f
is called the number of times and with the right parameters. 我们想要编写一个单元测试,检查
f
是否被称为次数和正确的参数。
def test_g():
with patch('mymodule.f') as function:
assert function.gacs.call_count == correct_no_calls
There is 有
function.assert_called_with(...)
but this only refers to the last call. 但这只是指最后一次通话。 So assuming
g
calls f(1,2)
and then f(2,3)
, function.assert_called_with(1,2)
is False
. 假设
g
调用f(1,2)
然后调用f(1,2)
f(2,3)
,则function.assert_called_with(1,2)
为False
。
Furthermore, there is 此外,还有
function.call_args_list
which yields a list of call
objects with the right parameters. 它产生一个具有正确参数的
call
对象列表。 Comparing this list to call
object that we create in the unit test feels like a very nasty thing to do. 将此列表与我们在单元测试中创建的
call
对象进行比较感觉就像是一件非常讨厌的事情。 call
seems like an internal class of the mock library. call
看起来像是mock库的内部类。
Is there a better way to do this? 有一个更好的方法吗? I use this set-up to test parallel execution of an
apply
function. 我使用此设置来测试
apply
函数的并行执行。
Even @MartinPieters's answer is correct I think that is not the best way to do it. 即使@ MartinPieters的答案是正确的,我认为这不是最好的方法。 Mock provide
assert_has_calls
to do this kind of duties. 模拟提供
assert_has_calls
来履行这种职责。
Your test could be: 你的测试可能是:
function.assert_has_calls([mock.call(1, 2), mock.call(2, 3)])
Where mock.call
is a helper class do to these kind of jobs. mock.call
是帮助类对这些工作做的事情。
Pay attention that is a has call and means the call list should be in the list of call and not equal. 注意这是一个有呼叫,意味着呼叫列表应该在呼叫列表中并且不相等。 To solve it I usually define my own helper
assert_is_calls()
as follow 为了解决这个问题,我通常会定义自己的帮助程序
assert_is_calls()
,如下所示
def assert_is_calls(m, calls, any_order=False):
assert len(m.mock_calls) == len(calls)
m.assert_has_calls(calls, any_order=any_order)
That a resume example 那是一个简历的例子
>>> import mock
>>> f = mock.Mock()
>>> f(1)
<Mock name='mock()' id='139836302999952'>
>>> f(2)
<Mock name='mock()' id='139836302999952'>
>>> f.assert_has_calls([mock.call(1), mock.call(2)])
>>> f.assert_has_calls([mock.call(2), mock.call(1)])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/damico/.local/lib/python2.7/site-packages/mock/mock.py", line 969, in assert_has_calls
), cause)
File "/home/damico/.local/lib/python2.7/site-packages/six.py", line 718, in raise_from
raise value
AssertionError: Calls not found.
Expected: [call(2), call(1)]
Actual: [call(1), call(2)]
>>> f.assert_has_calls([mock.call(2), mock.call(1)], any_order=True)
>>> f(3)
<Mock name='mock()' id='139836302999952'>
>>> f.assert_has_calls([mock.call(2), mock.call(1)], any_order=True)
>>> f.assert_has_calls([mock.call(1), mock.call(2)])
>>> assert len(f.mock_calls)==2
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AssertionError
>>> assert len(f.mock_calls)==3
>>> def assert_is_calls(m, calls, any_order=False):
... assert len(m.mock_calls) == len(calls)
... m.assert_has_calls(calls, any_order=any_order)
...
>>> assert_is_calls(f, [mock.call(1), mock.call(2), mock.call(3)])
>>> assert_is_calls(f, [mock.call(1), mock.call(3), mock.call(2)])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in assert_is_calls
File "/home/damico/.local/lib/python2.7/site-packages/mock/mock.py", line 969, in assert_has_calls
), cause)
File "/home/damico/.local/lib/python2.7/site-packages/six.py", line 718, in raise_from
raise value
AssertionError: Calls not found.
Expected: [call(1), call(3), call(2)]
Actual: [call(1), call(2), call(3)]
>>> assert_is_calls(f, [mock.call(1), mock.call(3), mock.call(2)], True)
>>> assert_is_calls(f, [mock.call(1), mock.call(3)], True)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in assert_is_calls
AssertionError
>>>
Test if the Mock().mock_calls
list is equal to a list of mock.call()
objects you provide: 测试
Mock().mock_calls
列表是否等于您提供的mock.call()
对象列表:
self.assertEquals(function.mock_calls, [
mock.call(1, 2),
mock.call(2, 3),
])
This gives you precise control, requiring both the order and the number of calls to match. 这为您提供了精确控制,同时要求匹配的顺序和呼叫数量。
The mock.call()
class is not internal, it is meant to be used for assertions like these. mock.call()
类不是内部的,它意味着用于这样的断言。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.