我们如何确保 Mock.call_args_list 中的调用包含参数与调用 Mock 对象时处于相同状态的调用?

2024-02-23

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包含调用模拟时而不是检查模拟参数时所有对象的状态?

我在用mock==1.0.1眼下。


这在文档部分进行了讨论26.6.3.7。应对可变参数 https://docs.python.org/3.5/library/unittest.mock-examples.html#coping-with-mutable-arguments.

不幸的是,他们确实没有任何优雅的解决方案来解决这个问题!推荐的解决方法是使用以下方法从可变参数中复制元素side_effect.

如果您为模拟提供 side_effect 函数,则将使用与模拟相同的参数调用 side_effect。这使我们有机会复制参数并将其存储以供以后断言。

在我看来,实施起来有点混乱。如果您需要在多个地方使用该功能,您可能更喜欢子类化Mock并直接添加该功能:

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).

>>> 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])
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

我们如何确保 Mock.call_args_list 中的调用包含参数与调用 Mock 对象时处于相同状态的调用? 的相关文章

随机推荐