我们如何确保Mock.call_args_list中的调用包含具有与调用Mock对象时相同状态的参数的调用? [英] How do we ensure that the calls in the Mock.call_args_list contain calls with arguments at the same state of when the Mock object was called?
问题描述
from mock import Mock
j = []
u = Mock()
u(j)
# At this point u.call_args_list == [call([])]
print u.call_args_list
j.append(100)
# At this point u.call_args_list == [call([100])], but I expect it to be [call([])], since it was never called when j had a value of 100 in it
print u.call_args_list
我的问题是,如何确保u.call_args_list
中的调用包含在调用模拟时而不是在检查模拟参数时的所有对象的状态?
My question is how do I ensure that the calls in u.call_args_list
contain the states of all objects at the time of calling the mock rather than at the time of checking the arguments of the mock?
此刻我正在使用mock==1.0.1
.
推荐答案
在文档部分不幸的是,他们对这个问题真的没有任何优雅的解决方案!推荐的解决方法是使用side_effect
从可变参数中复制元素.
Unfortunately, they don't really have any elegant solution to the issue! The recommended workaround is copying elements from the mutable arguments by using side_effect
.
如果为模拟提供了side_effect函数,则将以与模拟相同的args调用side_effect.这为我们提供了复制参数并将其存储以供以后声明的机会.
If you provide a side_effect function for a mock then side_effect will be called with the same args as the mock. This gives us an opportunity to copy the arguments and store them for later assertions.
我认为实施起来有些混乱.如果需要在多个地方使用该功能,则可能希望继承Mock
的子类并直接添加该功能:
It's somewhat messy to implement, in my opinion. If you need the capability in multiple places, you may prefer to subclass Mock
and add the feature directly:
from copy import deepcopy
class CopyingMock(MagicMock):
def __call__(self, *args, **kwargs):
args = deepcopy(args)
kwargs = deepcopy(kwargs)
return super(CopyingMock, self).__call__(*args, **kwargs)
2017 :现在可以在第三方发行版(pip install copyingmock
)中使用.
2017: It's now available in a third-party distribution (pip install copyingmock
).
>>> from copyingmock import CopyingMock
>>> mock = CopyingMock()
>>> list_ = [1,2]
>>> mock(list_)
<CopyingMock name='mock()' id='4366094008'>
>>> list_.append(3)
>>> mock.assert_called_once_with([1,2])
>>> mock.assert_called_once_with(list_)
AssertionError: Expected call: mock([1, 2, 3])
Actual call: mock([1, 2])
这篇关于我们如何确保Mock.call_args_list中的调用包含具有与调用Mock对象时相同状态的参数的调用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!