J'utilise la bibliothèque Mock pour tester mon application, mais je tiens à affirmer qu'aucune fonction n'a été appelée. Les documents factices évoquent des méthodes telles que mock.assert_called_with
et mock.assert_called_once_with
, mais je n'ai rien trouvé de tel que mock.assert_not_called
ou quelque chose permettant de vérifier que la commande simulée était PAS appelé .
Je pourrais aller avec quelque chose comme ce qui suit, bien que cela ne semble pas cool ni Pythonic:
def test_something:
# some actions
with patch('something') as my_var:
try:
# args are not important. func should never be called in this test
my_var.assert_called_with(some, args)
except AssertionError:
pass # this error being raised means it's ok
# other stuff
Des idées comment accomplir ceci?
Merci pour toute aide :)
Cela devrait fonctionner pour votre cas.
assert not my_var.called, 'method should not have been called'
Échantillon;
>>> mock=Mock()
>>> mock.a()
<Mock name='mock.a()' id='4349129872'>
>>> assert not mock.b.called, 'b was called and should not have been'
>>> assert not mock.a.called, 'a was called and should not have been'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AssertionError: a was called and should not have been
Bien qu’une vieille question, j’aimerais ajouter que la bibliothèque actuellement mock
(portage de unittest.mock) prend en charge la méthode assert_not_called
.
Juste améliorer le vôtre;
pip install mock --upgrade
Vous pouvez vérifier l'attribut called
, mais si votre assertion échoue, la prochaine chose que vous voudrez savoir, c'est quelque chose de à propos de l'appel inattendu. Vous pouvez donc également organiser l'affichage de ces informations dès le début. En utilisant unittest
, vous pouvez vérifier le contenu de call_args_list
à la place:
self.assertItemsEqual(my_var.call_args_list, [])
Quand cela échoue, cela donne un message comme ceci:
AssertionError: le nombre d'éléments n'était pas égal: Le premier a 0, le second a 1: call ('premier argument', 4)
Lorsque vous testez en utilisant class hérite de unittest.TestCase, vous pouvez simplement utiliser des méthodes telles que:
et similaire (dans documentation python vous trouvez le reste).
Dans votre exemple, nous pouvons simplement affirmer que la propriété mock_method.called est False, ce qui signifie que cette méthode n'a pas été appelée.
import unittest
from unittest import mock
import my_module
class A(unittest.TestCase):
def setUp(self):
self.message = "Method should not be called. Called {times} times!"
@mock.patch("my_module.method_to_mock")
def test(self, mock_method):
my_module.method_to_mock()
self.assertFalse(mock_method.called,
self.message.format(times=mock_method.call_count))
À en juger par d’autres réponses, personne à l’exception de @ rob-kennedy n’a parlé du call_args_list
.
C'est un outil puissant pour que vous puissiez implémenter l'exact contraire de MagicMock.assert_called_with()
call_args_list
est une liste d'objets call
. Chaque objet call
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)]
Consommer un objet call
est facile, car vous pouvez le comparer à 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 mots clés.
>>> ((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 consiste à:
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 si elle a été appelée avec un jeu d’arguments spécifique.
C'est utile. Supposons que vous souhaitiez tester une fonction prenant 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 simuler compute
et tester s'il a été appelé pour une valeur mais pas pour d'autres.
Avec python >= 3.5
, vous pouvez utiliser mock_object.assert_not_called()
.