A julgar por outras respostas, ninguém, exceto @ rob-kennedy, falou sobre o call_args_list
.
É uma ferramenta poderosa para a qual você pode implementar exatamente o contrário de MagicMock.assert_called_with()
call_args_list
é uma lista de call
objetos. Cada call
objeto representa uma chamada feita em uma chamada simulada.
>>> 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)]
Consumir um call
objeto é fácil, pois você pode compará-lo com uma tupla de comprimento 2, onde o primeiro componente é uma tupla contendo todos os argumentos posicionais da chamada relacionada, enquanto o segundo componente é um dicionário dos argumentos da palavra-chave.
>>> ((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
Portanto, uma maneira de abordar o problema específico do OP é
def test_something():
with patch('something') as my_var:
assert ((some, args),) not in my_var.call_args_list
Observe que dessa maneira, em vez de apenas verificar se uma chamada simulada foi chamada, via MagicMock.called
, agora você pode verificar se ela foi chamada com um conjunto específico de argumentos.
Isso é útil. Digamos que você queira testar uma função que recebe uma lista e chama outra função compute()
, para cada valor da lista somente se eles satisfizerem uma condição específica.
Agora você pode zombar compute
e testar se foi chamado com algum valor, mas não com outros.