À en juger par d'autres réponses, personne à l'exception de @ rob-kennedy n'a parlé de call_args_list
.
C'est un outil puissant pour lequel vous pouvez implémenter exactement le contraire de MagicMock.assert_called_with()
call_args_list
est une liste d' call
objets. Chaque call
objet représente un appel effectué sur un appelable simulé.
>>> 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)]
La consommation d'un call
objet est facile, car vous pouvez le comparer avec un tuple de longueur 2 où le premier composant est un tuple contenant tous les arguments de position de l'appel associé, tandis que le second composant est un dictionnaire des arguments de mot-clé.
>>> ((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
Ainsi, un moyen de résoudre le problème spécifique du PO est
def test_something():
with patch('something') as my_var:
assert ((some, args),) not in my_var.call_args_list
Notez que de cette façon, au lieu de simplement vérifier si un appelable simulé a été appelé, via MagicMock.called
, vous pouvez maintenant vérifier s'il a été appelé avec un ensemble spécifique d'arguments.
C'est utile. Supposons que vous souhaitiez tester une fonction qui prend une liste et appeler une autre fonction,, compute()
pour chacune des valeurs de la liste uniquement si elles satisfont à une condition spécifique.
Vous pouvez maintenant vous moquer compute
et tester si elle a été appelée sur une valeur mais pas sur d'autres.