我们如何确保 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?(我们如何确保 Mock.call_args_list 中的调用包含具有与调用 Mock 对象时相同状态的参数的调用?) - IT屋-
本文介绍了我们如何确保 Mock.call_args_list 中的调用包含具有与调用 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

我的问题是如何确保 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.

推荐答案

这在文档部分进行了讨论 26.6.3.7.处理可变参数.

This is discussed in the documentation section 26.6.3.7. Coping with mutable arguments.

不幸的是,他们对这个问题并没有任何优雅的解决方案!推荐的解决方法是使用 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 函数,那么将使用与模拟相同的参数调用 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 对象时相同状态的参数的调用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

patching a class yields quot;AttributeError: Mock object has no attributequot; when accessing instance attributes(修补类会产生“AttributeError:Mock object has no attribute;访问实例属性时)
How to mock lt;ModelClassgt;.query.filter_by() in Flask-SqlAlchemy(如何在 Flask-SqlAlchemy 中模拟 lt;ModelClassgt;.query.filter_by())
FTPLIB error socket.gaierror: [Errno 8] nodename nor servname provided, or not known(FTPLIB 错误 socket.gaierror: [Errno 8] nodename nor servname provided, or not known)
Weird numpy.sum behavior when adding zeros(添加零时奇怪的 numpy.sum 行为)
Why does the #39;int#39; object is not callable error occur when using the sum() function?(为什么在使用 sum() 函数时会出现 int object is not callable 错误?)
How to sum in pandas by unique index in several columns?(如何通过几列中的唯一索引对 pandas 求和?)