检查是否使用不同参数多次调用函数
Checking whether function has been called multiple times with different parameters
假设我们有一个函数f(x,y)
和另一个函数
def g():
# ...
f(i,j) # i,j vary and f is called multiple times
# ...
我们想编写一个单元测试来检查 f
被调用的次数和参数是否正确。
def test_g():
with patch('mymodule.f') as function:
assert function.gacs.call_count == correct_no_calls
有
function.assert_called_with(...)
但这只是指最后一次通话。所以假设 g
调用 f(1,2)
然后 f(2,3)
,function.assert_called_with(1,2)
是 False
.
此外,还有
function.call_args_list
这会生成一个包含 call
个具有正确参数的对象的列表。将此列表与我们在单元测试中创建的 call
对象进行比较感觉是一件非常讨厌的事情。 call
似乎是模拟库的内部 class。
有更好的方法吗?我使用此设置来测试 apply
函数的并行执行。
测试您提供的 Mock().mock_calls
list is equal to a list of mock.call()
objects 是否:
self.assertEquals(function.mock_calls, [
mock.call(1, 2),
mock.call(2, 3),
])
这为您提供了精确的控制,要求调用顺序和调用次数都匹配。
mock.call()
class 不是内部的,它旨在用于此类断言。
即使@MartinPieters 的回答是正确的,我认为这不是最好的方法。模拟提供 assert_has_calls
来完成这种职责。
您的测试可能是:
function.assert_has_calls([mock.call(1, 2), mock.call(2, 3)])
其中 mock.call
是帮手 class 从事此类工作。
注意是has调用,表示调用列表应该在调用列表中,不相等。为了解决这个问题,我通常定义自己的助手 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)
简历范例
>>> 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
>>>
假设我们有一个函数f(x,y)
和另一个函数
def g():
# ...
f(i,j) # i,j vary and f is called multiple times
# ...
我们想编写一个单元测试来检查 f
被调用的次数和参数是否正确。
def test_g():
with patch('mymodule.f') as function:
assert function.gacs.call_count == correct_no_calls
有
function.assert_called_with(...)
但这只是指最后一次通话。所以假设 g
调用 f(1,2)
然后 f(2,3)
,function.assert_called_with(1,2)
是 False
.
此外,还有
function.call_args_list
这会生成一个包含 call
个具有正确参数的对象的列表。将此列表与我们在单元测试中创建的 call
对象进行比较感觉是一件非常讨厌的事情。 call
似乎是模拟库的内部 class。
有更好的方法吗?我使用此设置来测试 apply
函数的并行执行。
测试您提供的 Mock().mock_calls
list is equal to a list of mock.call()
objects 是否:
self.assertEquals(function.mock_calls, [
mock.call(1, 2),
mock.call(2, 3),
])
这为您提供了精确的控制,要求调用顺序和调用次数都匹配。
mock.call()
class 不是内部的,它旨在用于此类断言。
即使@MartinPieters 的回答是正确的,我认为这不是最好的方法。模拟提供 assert_has_calls
来完成这种职责。
您的测试可能是:
function.assert_has_calls([mock.call(1, 2), mock.call(2, 3)])
其中 mock.call
是帮手 class 从事此类工作。
注意是has调用,表示调用列表应该在调用列表中,不相等。为了解决这个问题,我通常定义自己的助手 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)
简历范例
>>> 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
>>>