J'essaie de tester un code hérité, en utilisant Mockito.
Je veux écraser un FooDao
qui est utilisé dans la production comme suit:
foo = fooDao.getBar(new Bazoo());
Je peux écrire:
when(fooDao.getBar(new Bazoo())).thenReturn(myFoo);
Mais le problème évident est qu'il getBar()
n'est jamais appelé avec le même Bazoo
objet que celui pour lequel j'ai stoppé la méthode. (Maudissez cet new
opérateur!)
Je serais ravi si je pouvais écraser la méthode de manière à ce qu'elle renvoie myFoo
quel que soit l'argument. À défaut, j'écouterai d'autres suggestions de contournement, mais j'aimerais vraiment éviter de changer le code de production jusqu'à ce qu'il y ait une couverture de test raisonnable.
la source
notNull(Bazoo.class)
juste commeany(Bazoo.class)
(peut-être qu'il n'existait pas au moment de cette réponse)Bazoo
ouCazoo
qui sont tous les deux des sous-classes de, disonsAzoo
. carBazoo
j'avais besoin de revenirfoo
, maisCazoo
j'avais besoin de revenirbar
. dans cette situation, laMatchers.any()
solution proposée ne fonctionne pas, cependant,Matchers.isA()
fonctionne parfaitement.org.mockito.Matchers
est désormais obsolète - utilisez-le à laorg.mockito.ArgumentMatchers
place, c'est-à-direimport static org.mockito.ArgumentMatchers.*
(voir la documentation )when(myFoo.knowsWhatsUp()).thenReturn(myMoney);
Utilisez comme ceci:
Avant d'importer
Mockito.Matchers
la source
http://site.mockito.org/mockito/docs/1.10.19/org/mockito/Matchers.html
anyObject()
devrait répondre à vos besoins.En outre, vous pouvez toujours envisager d'implémenter
hashCode()
etequals()
pour laBazoo
classe. Cela ferait fonctionner votre exemple de code comme vous le souhaitez.la source
Une autre option consiste à s'appuyer sur une bonne
equals
méthode à l' ancienne . Tant que l'argument dans lawhen
maquette estequals
l'argument dans le code testé, alors Mockito correspondra à la maquette.Voici un exemple.
puis, en supposant que vous savez quelle sera la valeur
someField
, vous pouvez vous en moquer comme ceci.avantages: C'est plus explicite que les
any
matchers. En tant que réviseur de code, je garde un œil ouvertany
dans l'écriture de code pour les développeurs juniors, car il jette un coup d'œil sur la logique de leur code pour générer l'objet approprié transmis.con: Parfois, le champ transmis à l'objet est un ID aléatoire. Dans ce cas, vous ne pouvez pas facilement construire l'objet argument attendu dans votre code maquette.
Une autre approche possible consiste à utiliser l'
Answer
objet de Mockito qui peut être utilisé avec lawhen
méthode.Answer
vous permet d'intercepter l'appel réel, d'inspecter l'argument d'entrée et de renvoyer un objet factice. Dans l'exemple ci-dessous, j'utiliseany
pour intercepter toute demande concernant la méthode à moquer. Mais ensuite, dans leAnswer
lambda, je peux inspecter davantage l'argument Bazo ... peut-être pour vérifier qu'une ID appropriée lui a été transmise. Je préfère celaany
par lui-même afin qu'au moins une certaine inspection soit faite sur l'argument.Donc, pour résumer le tout, j'aime me baser sur
equals
(où l'argument attendu et l'argument réel doivent être égaux) et si l'égalité n'est pas possible (en raison de ne pas pouvoir prédire l'état de l'argument réel), je vais recourir pourAnswer
inspecter l'argument.la source