简体   繁体   English

我如何检查调用参数是否会随unittest.mock一起更改

[英]How can i check call arguments if they will change with unittest.mock

One of my classes accumulates values in a list, uses the list as an argument to a method on another object and deletes some of the values in this list. 我的一个类在列表中累积值,将该列表用作另一个对象上方法的参数,并删除此列表中的某些值。 Something like 就像是

element = element_source.get()
self.elements.append(element)
element_destination.send(elements)
self.remove_outdated_elements()

But when when i was trying to test this behavior, i've found that mocks don't copy their arguments. 但是,当我尝试测试这种行为时,我发现模拟程序不会复制其参数。

>>> from unittest.mock import Mock
>>> m = Mock()
>>> a = [1]
>>> m(a)
<Mock name='mock()' id='139717658759824'>
>>> m.call_args
call([1])
>>> a.pop()
1
>>> m.assert_called_once_with([1])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.3/unittest/mock.py", line 737, in assert_called_once_with
    return self.assert_called_with(*args, **kwargs)
  File "/usr/lib/python3.3/unittest/mock.py", line 726, in assert_called_with
    raise AssertionError(msg)
AssertionError: Expected call: mock([1])
Actual call: mock([])

Is there a way to make Mock copy it's call arguments? 有没有办法使Mock复制它的调用参数? If not, what is the best way to test this kind of behavior? 如果不是,测试这种行为的最佳方法是什么?

There is a chapter " Coping with mutable arguments " in the documentation, which suggests several solutions to your problem. 文档中有一章“ 应对可变参数 ”,为您的问题提供了几种解决方案。

I'd go with this one: 我会选择这个:

>>> 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)
...
>>> c = CopyingMock(return_value=None)
>>> arg = set()
>>> c(arg)
>>> arg.add(1)
>>> c.assert_called_with(set())
>>> c.assert_called_with(arg)
Traceback (most recent call last):
    ...
AssertionError: Expected call: mock(set([1]))
Actual call: mock(set([]))
>>> c.foo
<CopyingMock name='mock.foo' id='...'>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM