Судя по другим ответам, никто, кроме @ rob-kennedy, не говорил о call_args_list
.
Это мощный инструмент, позволяющий реализовать прямо противоположное MagicMock.assert_called_with()
call_args_list
это список call
объектов. Каждый call
объект представляет собой вызов фиктивного вызываемого объекта.
>>> from unittest.mock import MagicMock
>>> m = MagicMock()
>>> m.call_args_list
[]
>>> m(42)
<MagicMock name='mock()' id='139675158423872'>
>>> m.call_args_list
[call(42)]
>>> m(42, 30)
<MagicMock name='mock()' id='139675158423872'>
>>> m.call_args_list
[call(42), call(42, 30)]
Использовать call
объект легко, так как вы можете сравнить его с кортежем длиной 2, где первый компонент - это кортеж, содержащий все позиционные аргументы связанного вызова, а второй компонент - словарь аргументов ключевого слова.
>>> ((42,),) in m.call_args_list
True
>>> m(42, foo='bar')
<MagicMock name='mock()' id='139675158423872'>
>>> ((42,), {'foo': 'bar'}) in m.call_args_list
True
>>> m(foo='bar')
<MagicMock name='mock()' id='139675158423872'>
>>> ((), {'foo': 'bar'}) in m.call_args_list
True
Итак, способ решения конкретной проблемы OP -
def test_something():
with patch('something') as my_var:
assert ((some, args),) not in my_var.call_args_list
Обратите внимание, что таким образом, вместо того, чтобы просто проверять, был ли вызван фиктивный вызываемый объект через MagicMock.called
, теперь вы можете проверить, был ли он вызван с определенным набором аргументов.
Это полезно. Допустим, вы хотите протестировать функцию, которая принимает список и вызывает другую функцию compute()
, для каждого значения списка, только если они удовлетворяют определенному условию.
Теперь вы можете поиздеваться compute
и проверить, было ли вызвано какое-то значение, а не другое.