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?

前端 未结 1 1973
我在风中等你
我在风中等你 2020-12-04 02:21
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 ==          


        
相关标签:
1条回答
  • 2020-12-04 02:52

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

    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.

    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.

    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: 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])
    
    0 讨论(0)
提交回复
热议问题