Se moquant de assert_called_with en Python
J'ai un peu de mal à comprendre pourquoi le code suivant ne passe pas:
test.py
import mock
import unittest
from foo import Foo
class TestFoo(unittest.TestCase):
@mock.patch('foo.Bar')
def test_foo_add(self, Bar):
foo = Foo()
foo.add(2, 2)
Bar.add.assert_called_with(2, 2)
if __name__ == '__main__':
unittest.main()
foo.py
from bar import Bar
class Foo(object):
def add(self, x, y):
bar = Bar()
return bar.add(x, y)
bar.py
class Bar(object):
def add(self, x, y):
print('b.Bar --> Adding {} + {}'.format(x, y))
return x + y
Dans le code, Foo.add
crée une instance de Bar
et retourne le résultat de Bar.add
lorsqu'ils sont invoqués. Pourquoi n'essais assert_called_with
pour Bar.add
échec? Je crois que je suis se moquer de la Bar
au bon endroit (je suis moqueur foo.Bar
parce que c'est l'espace de noms dont il est à l'étude, plutôt que de bar.Bar
).
Traceback (most recent call last):
Le fichier "/Users/iain/PycharmProjects/testing/venv/lib/python2.7/site-packages/mock.py", ligne 1201, dans patché
retour func(*args, **keywargs)
Fichier "test.py", ligne 12, dans test_a_b
fake_Bar.ajouter.assert_called_with(2, 2)
Le fichier "/Users/iain/PycharmProjects/testing/venv/lib/python2.7/site-packages/mock.py" de ligne, 831, dans assert_called_with
soulever AssertionError (on Attend d'appel: %s\n appelé' % (attendus,))
AssertionError: visite Attendue: add(2, 2)
Pas appelé
OriginalL'auteur Iain | 2015-06-08
Vous devez vous connecter pour publier un commentaire.
Vous êtes moqueur de l'appel de méthode à la bonne place. Cependant, puisque vous êtes l'appel de la méthode à partir d'une instance, c'est une méthode liée, et reçoit ainsi une instance comme le premier argument (le
self
paramètre), en plus de tous les autres arguments.Modifier: Depuis
Bar
est remplacé par unMock
exemple,Bar().add
ne sais pas c'est une méthode (et n'est donc pas lié à quoi que ce soit). En d'autres termes,Bar
est unMock
,Bar()
est unMock
, etBar().add
est aussi unMock
.bar.add
est donc une nouvelle maquette, appelée avec des arguments(2, 2)
. Une manière d'affirmer que cet appel serait:Selon la façon dont votre code des regards, vous pouvez au lieu de se moquer de la méthode plutôt que de la classe:
foo
est passé comme premier argument àBar.add.assert_called_with()
mais encore le test échoue? La sortie du lit la même (AssertionError: visite Attendue: ajouter(<foo.Objet Foo à 0x102108a50>, 2, 2) Pas appelé)Oups, mon exemple de code est totalement fausse. Sera mise à jour dans quelques avec la bonne réponse. Désolé!
Merci! Je pense que je suis tombé fait l'erreur de penser que si j'ai raillé
foo.Bar
ensuite, l'ensemble de ses attributs et ses méthodes est restée intacte et inchangée, à moins que j'ai explicitement changé leur comportement . Serait-ce un cas où on peut utiliser lemock.patch.object
méthode à la place?patch.object
etpatch
ont des fonctionnalités identiques; ils ont tout simplement utiliser un autre moyen de faire référence à l'objet de patch. Pour patchBar
dans lefoo
module, vous pouvez utilisermock.patch(foo, 'Bar')
, et que le résultat serait le même. Je ne sais pas de pré-construites de façon d'obtenir le comportement que vous voulez, malheureusement.OriginalL'auteur Felipe
Je crois que votre problème sera résolu comme ceci:
OriginalL'auteur wakooo