Это обсуждается в разделе документации 26.6.3.7. Копирование с изменяемыми аргументами .
К сожалению, у них действительно нет элегантного решения проблемы! Рекомендуемое обходное решение - копирование элементов из изменяемых аргументов с помощью side_effect
.
Если вы предоставляете функцию side_effect для макета, то side_effect будет вызываться с теми же аргументами, что и mock. Это дает нам возможность скопировать аргументы и сохранить их для последующих утверждений.
blockquote>На мой взгляд, это довольно сложно реализовать. Если вам нужна возможность в нескольких местах, вы можете предпочесть подкласс
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_)
>>> 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])