Python 如何确保Mock.call_args_列表中的调用包含参数与调用Mock对象时处于相同状态的调用?

Python 如何确保Mock.call_args_列表中的调用包含参数与调用Mock对象时处于相同状态的调用?,python,unit-testing,mocking,Python,Unit Testing,Mocking,我的问题是如何确保u.call\u args\u list中的调用包含调用mock时所有对象的状态,而不是检查mock参数时的状态 目前我正在使用mock==1.0.1。这将在文档部分讨论 不幸的是,他们没有任何优雅的解决方案!建议的解决方法是使用副作用从可变参数复制元素 from copy import deepcopy class CopyingMock(MagicMock): def __call__(self, *args, **kwargs): args =

我的问题是如何确保
u.call\u args\u list
中的调用包含调用mock时所有对象的状态,而不是检查mock参数时的状态


目前我正在使用
mock==1.0.1

这将在文档部分讨论

不幸的是,他们没有任何优雅的解决方案!建议的解决方法是使用
副作用
从可变参数复制元素

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)
如果为mock提供了side_effect函数,那么side_effect将使用与mock相同的参数调用。这使我们有机会复制参数并存储它们以供以后断言

在我看来,实施起来有点混乱。如果您在多个位置需要该功能,您可能更愿意将
Mock
子类化,并直接添加该功能:

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

2017:现在可在第三方发行版(
pip安装copyingmock
)中使用

>>>从copyingmock导入copyingmock
>>>mock=CopyingMock()
>>>列表=[1,2]
>>>模拟(列表)
>>>列表附加(3)
>>>mock.assert_调用_一次_,使用([1,2])
>>>mock.assert_调用_once_(列表_)
AssertionError:预期调用:mock([1,2,3])
实际调用:mock([1,2])
>>> 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])