【问题标题】:How can i check call arguments if they will change with unittest.mock我如何检查调用参数是否会随 unittest.mock 改变
【发布时间】:2013-04-26 12:47:54
【问题描述】:

我的一个类在一个列表中累积值,将该列表用作另一个对象的方法的参数,并删除该列表中的一些值。类似的东西

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

但是当我尝试测试这种行为时,我发现模拟不会复制它们的参数。

>>> 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([])

有没有办法让 Mock 复制它的调用参数?如果不是,那么测试这种行为的最佳方法是什么?

【问题讨论】:

    标签: python mocking


    【解决方案1】:

    文档中有一个章节“Coping with mutable arguments”,它为您的问题提出了几种解决方案。

    我会选择这个:

    >>> 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='...'>
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-25
    • 2016-04-28
    • 1970-01-01
    • 1970-01-01
    • 2022-01-04
    • 2013-10-27
    • 1970-01-01
    相关资源
    最近更新 更多