J'utilise Mockito 1.9.0. Je veux simuler le comportement d'une seule méthode d'une classe dans un test JUnit, j'ai donc
final MyClass myClassSpy = Mockito.spy(myInstance);
Mockito.when(myClassSpy.method1()).thenReturn(myResults);
Le problème est, dans la deuxième ligne, myClassSpy.method1()
est en fait appelé, ce qui entraîne une exception. La seule raison pour laquelle j'utilise des simulateurs est que plus tard, à chaque myClassSpy.method1()
appel, la vraie méthode ne sera pas appelée et l' myResults
objet sera retourné.
MyClass
est une interface et myInstance
est une implémentation de cela, si cela importe.
Que dois-je faire pour corriger ce comportement d'espionnage?
Réponses:
Permettez-moi de citer la documentation officielle :
Dans votre cas, cela va quelque chose comme:
la source
send
est appeléeMon cas était différent de la réponse acceptée. J'essayais de simuler une méthode de package privé pour une instance qui ne vivait pas dans ce package
et les classes de test
La compilation est correcte, mais lorsqu'elle essaie de configurer le test, elle appelle à la place la vraie méthode.
Déclarer la méthode protégée ou publique résout le problème, mais ce n'est pas une solution propre.
la source
Dans mon cas, en utilisant Mockito 2.0, j'ai dû changer tous les
any()
paramètres pournullable()
afin de bloquer le véritable appel.la source
foo = Mockito.spy(foo);
Mockito.doReturn(someValue).when(foo).methodToPrevent(nullable(ArgumentType.class));
any
et leseq
apparieurs.La réponse de Tomasz Nurkiewicz ne semble pas raconter toute l'histoire!
NB Mockito version: 1.10.19.
Je suis vraiment un newb Mockito, donc je ne peux pas expliquer le comportement suivant: s'il y a un expert qui peut améliorer cette réponse, n'hésitez pas.
La méthode en question ici
getContentStringValue
, n'est PASfinal
et NONstatic
.Cette ligne fait appel à la méthode originale
getContentStringValue
:Cette ligne n'appelle pas la méthode d'origine
getContentStringValue
:Pour des raisons auxquelles je ne peux pas répondre, l'utilisation
isA()
entraîne l'doReturn
échec du comportement (?) "Ne pas appeler la méthode" prévu .Regardons les signatures de méthode impliquées ici: ce sont les deux
static
méthodes deMatchers
. Le Javadoc dit que les deux sont de retournull
, ce qui est un peu difficile à comprendre. Vraisemblablement l'Class
objet passé comme paramètre est examiné mais le résultat n'a jamais été calculé ou rejeté. Étant donné que celanull
peut représenter n'importe quelle classe et que vous espérez que la méthode simulée ne sera pas appelée, les signaturesisA( ... )
et leany( ... )
retour ne pourraient-ils pas être renvoyésnull
plutôt qu'un paramètre générique *<T>
?En tous cas:
La documentation de l'API ne donne aucun indice à ce sujet. Il semble également que la nécessité d'un tel comportement "ne pas appeler la méthode" soit "très rare". Personnellement, j'utilise cette technique tout le temps : en général, je trouve que la moquerie implique quelques lignes qui "définissent la scène" ... suivies par l'appel d'une méthode qui "reproduit" ensuite la scène dans le contexte simulé que vous avez mis en scène .. .et pendant que vous installez le décor et les accessoires, la dernière chose que vous voulez, c'est que les acteurs entrent à gauche et commencent à jouer leur cœur ...
Mais c'est bien au-delà de ma note salariale ... J'invite des explications de tous les grands prêtres Mockito de passage ...
* "paramètre générique" est-il le bon terme?
la source
Un autre scénario possible qui peut provoquer des problèmes avec les espions est lorsque vous testez des beans de printemps (avec un framework de test de printemps) ou un autre framework qui procède au proxy de vos objets pendant le test .
Exemple
Dans le code ci-dessus, Spring et Mockito essaieront de proxy votre objet MonitoringDocumentsRepository, mais Spring sera le premier, ce qui provoquera un appel réel de la méthode findMonitoringDocuments. Si nous déboguons notre code juste après avoir mis un espion sur un objet de dépôt, il ressemblera à ceci dans le débogueur:
@SpyBean à la rescousse
Si au lieu d'
@Autowired
annotation, nous utilisons l'@SpyBean
annotation, nous résoudrons le problème ci-dessus, l'annotation SpyBean injectera également un objet de référentiel mais il sera d'abord mandaté par Mockito et ressemblera à ceci à l'intérieur du débogueuret voici le code:
la source
J'ai trouvé une autre raison pour que l'espion appelle la méthode originale.
Quelqu'un a eu l'idée de se moquer d'une
final
classe et a découvertMockMaker
:Source: https://github.com/mockito/mockito/wiki/What%27s-new-in-Mockito-2#mock-the-unmockable-opt-in-mocking-of-final-classesmethods
Après avoir fusionné et apporté ce fichier sur ma machine, mes tests ont échoué.
J'ai juste dû supprimer la ligne (ou le fichier), et j'ai
spy()
travaillé.la source
Un peu tard pour la fête mais les solutions ci-dessus n'ont pas fonctionné pour moi, donc partager mes 0,02 $
Version Mokcito: 1.10.19
MyClass.java
Test.java
Ce qui suit n'a PAS fonctionné pour moi (la méthode actuelle était appelée):
1.
2.
3.
SUIVI:
la source
Une façon de s'assurer qu'une méthode d'une classe n'est pas appelée est de remplacer la méthode par un mannequin.
la source
Réponse pour les utilisateurs de scala: Même mettre en
doReturn
premier ne fonctionne pas! Voir cet article .la source