Ok, que diriez-vous de n'importe quel framework de moquage java en général ... Est-ce possible avec n'importe quel autre framework, ou devrais-je simplement créer un stub stupide pour imiter le comportement que je veux?
Abhijeet Kashnia
Réponses:
1001
Vous pouvez créer une réponse dans Mockito. Supposons que nous avons une interface nommée Application avec une méthode myFunction.
C'est ce que je cherchais aussi. Je vous remercie! Mais mon problème était différent. Je veux me moquer d'un service de persistance (EJB) qui stocke des objets et les renvoie par nom.
migu
7
J'ai créé une classe supplémentaire qui encapsule la création de la réponse. Donc le code se lit commewhen(...).then(Return.firstParameter())
SpaceTrucker
69
Avec Java 8 lambdas, il est facile de retourner le premier argument, même pour une classe spécifique, c'est-à-dire when(foo(any()).then(i -> i.getArgumentAt(0, Bar.class)). Et vous pouvez tout aussi bien utiliser une référence de méthode et appeler une méthode réelle.
Paweł Dyda
Cela résout mon problème avec une méthode de retour Iterator<? extends ClassName>qui provoque toutes sortes de problèmes de transtypage dans une thenReturn()instruction.
Michael Shopsin
16
Avec Java 8 et Mockito <1.9.5, la réponse de Paweł devientwhen(foo(any()).thenAnswer(i -> i.getArguments()[0])
Graeme Moss
567
Si vous avez Mockito 1.9.5 ou supérieur, il existe une nouvelle méthode statique qui peut créer l' Answerobjet pour vous. Vous devez écrire quelque chose comme
Notez que la returnsFirstArg()méthode est statique dans la AdditionalAnswersclasse, ce qui est nouveau pour Mockito 1.9.5; vous aurez donc besoin de la bonne importation statique.
Remarque: c'est when(...).then(returnsFirstArg()), j'ai eu par erreur when(...).thenReturn(returnsFirstArg())qui a donnéjava.lang.ClassCastException: org.mockito.internal.stubbing.answers.ReturnsArgumentAt cannot be cast to
Benedikt Köppel
1
Remarque: renvoieFirstArg () renvoie la réponse <> plutôt que la valeur de l'argument. Got 'Foo (java.lang.String) ne peut pas être appliqué à' (org.mockito.stubbing.Answer <java.lang.Object>) 'tout en essayant d'appeler .thenReturn (new Foo (ReturnsFirstArg ()))
Lu55
J'ai toujours besoin de google cette réponse encore et encore et encore au cours des dernières années, car je ne me souviens tout simplement pas "AdditionalAnswers" et j'en ai juste besoin très rarement. Ensuite, je me demande comment diable je peux construire ce scénario car je ne peux pas trouver les dépendances nécessaires. Ne pourrait-il pas simplement être ajouté directement à mockito? : /
BAERUS
2
La réponse de Steve est plus générique. Celui-ci vous permet uniquement de renvoyer l'argument brut. Si vous souhaitez traiter cet argument et renvoyer le résultat, alors la réponse de Steve est la règle. J'ai voté pour les deux car ils sont tous les deux utiles.
akostadinov
Pour info, nous devons importer static org.mockito.AdditionalAnswers.returnsFirstArg. ceci pour utiliser ReturnsFirstArg. Aussi, je peux le faire when(myMock.myFunction(any())).then(returnsFirstArg())dans Mockito 2.20. *
gtiwari333
78
Avec Java 8, il est possible de créer une réponse sur une seule ligne, même avec une ancienne version de Mockito:
Bien sûr, cela n'est pas aussi utile que l'utilisation AdditionalAnswerssuggérée par David Wallace, mais peut être utile si vous souhaitez transformer l'argument "à la volée".
Brillant. Je vous remercie. Si l'argument est long, cela peut-il encore fonctionner avec la boxe et Long.class?
vikingsteve
1
.getArgumentAt (..) n'a pas été trouvé pour moi mais .getArgument (1) a fonctionné (mockito 2.6.2)
Curtis Yallop
41
J'ai eu un problème très similaire. L'objectif était de se moquer d'un service qui persiste sur les objets et peut les renvoyer par leur nom. Le service ressemble à ceci:
C'est une question assez ancienne mais je pense qu'elle est toujours d'actualité. De plus, la réponse acceptée ne fonctionne que pour String. En attendant, il y a Mockito 2.1 et certaines importations ont changé, je voudrais donc partager ma réponse actuelle:
importstatic org.mockito.AdditionalAnswers.returnsFirstArg;importstatic org.mockito.ArgumentMatchers.any;importstatic org.mockito.Mockito.when;@MockprivateMyClass myClass;// this will return anything you pass, but it's pretty unrealistic
when(myClass.myFunction(any())).then(returnsFirstArg());// it is more "life-like" to accept only the right type
when(myClass.myFunction(any(ClassOfArgument.class))).then(returnsFirstArg());
J'utilise quelque chose de similaire (en gros c'est la même approche). Parfois, il est utile qu'un objet simulé renvoie une sortie prédéfinie pour certaines entrées. Cela se passe comme ceci:
privateHashtable<InputObject,OutputObject> table =newHashtable<InputObject,OutputObject>();
table.put(input1, ouput1);
table.put(input2, ouput2);...
when(mockObject.method(any(InputObject.class))).thenAnswer(newAnswer<OutputObject>(){@OverridepublicOutputObject answer(finalInvocationOnMock invocation)throwsThrowable{InputObject input =(InputObject) invocation.getArguments()[0];if(table.containsKey(input)){return table.get(input);}else{returnnull;// alternatively, you could throw an exception}}});
Vous souhaiterez peut-être utiliser verify () en combinaison avec ArgumentCaptor pour assurer l'exécution dans le test et ArgumentCaptor pour évaluer les arguments:
ArgumentCaptor<String> argument =ArgumentCaptor.forClass(String.class);
verify(mock).myFunction(argument.capture());
assertEquals("the expected value here", argument.getValue());
La valeur de l'argument est évidemment accessible via l'argument.getValue () pour une manipulation / vérification / autre.
C'est un peu vieux, mais je suis venu ici parce que j'avais le même problème. J'utilise JUnit mais cette fois dans une application Kotlin avec mockk. Je poste un échantillon ici pour référence et comparaison avec l'homologue Java:
@Test
fun demo(){// mock a sample function
val aMock:(String)->(String)= mockk()// make it return the same as the argument on every invocation
every {
aMock.invoke(any())} answers {
firstArg()}// test it
assertEquals("senko", aMock.invoke("senko"))
assertEquals("senko1", aMock.invoke("senko1"))
assertNotEquals("not a senko", aMock.invoke("senko"))}
//Use ArgumentCaptor to capture the valueArgumentCaptor<String> param =ArgumentCaptor.forClass(String.class);
when(mock.myFunction(param.capture())).thenAnswer(newAnswer<String>(){@OverridepublicString answer(InvocationOnMock invocation)throwsThrowable{return param.getValue();//return the captured value.}});
OU si vous êtes fan de lambda, faites simplement:
//Use ArgumentCaptor to capture the valueArgumentCaptor<String> param =ArgumentCaptor.forClass(String.class);
when(mock.myFunction(param.capture())).thenAnswer((invocation)-> param.getValue());
Résumé: utilisez argumentcaptor pour capturer le paramètre transmis. Plus tard dans la réponse, renvoyez la valeur capturée à l'aide de getValue.
Cela ne fonctionne plus (plus?). Concernant les documents: Cette méthode doit être utilisée à l'intérieur de la vérification. Cela signifie que vous ne pouvez capturer la valeur qu'en utilisant la méthode de vérification
Muhammed Misir
1. Je ne sais pas ce que vous entendez par ce que This doesn´t work (anymore?).je travaille sur mon instance. 2. Désolé, je ne suis pas clair sur le point que vous essayez de faire valoir. La réponse est spécifique à la question d'OP.
Réponses:
Vous pouvez créer une réponse dans Mockito. Supposons que nous avons une interface nommée Application avec une méthode myFunction.
Voici la méthode de test avec une réponse Mockito:
Depuis Mockito 1.9.5 et Java 8, vous pouvez également utiliser une expression lambda:
la source
when(...).then(Return.firstParameter())
when(foo(any()).then(i -> i.getArgumentAt(0, Bar.class))
. Et vous pouvez tout aussi bien utiliser une référence de méthode et appeler une méthode réelle.Iterator<? extends ClassName>
qui provoque toutes sortes de problèmes de transtypage dans unethenReturn()
instruction.when(foo(any()).thenAnswer(i -> i.getArguments()[0])
Si vous avez Mockito 1.9.5 ou supérieur, il existe une nouvelle méthode statique qui peut créer l'
Answer
objet pour vous. Vous devez écrire quelque chose commeOu bien
Notez que la
returnsFirstArg()
méthode est statique dans laAdditionalAnswers
classe, ce qui est nouveau pour Mockito 1.9.5; vous aurez donc besoin de la bonne importation statique.la source
when(...).then(returnsFirstArg())
, j'ai eu par erreurwhen(...).thenReturn(returnsFirstArg())
qui a donnéjava.lang.ClassCastException: org.mockito.internal.stubbing.answers.ReturnsArgumentAt cannot be cast to
static org.mockito.AdditionalAnswers.returnsFirstArg
. ceci pour utiliser ReturnsFirstArg. Aussi, je peux le fairewhen(myMock.myFunction(any())).then(returnsFirstArg())
dans Mockito 2.20. *Avec Java 8, il est possible de créer une réponse sur une seule ligne, même avec une ancienne version de Mockito:
Bien sûr, cela n'est pas aussi utile que l'utilisation
AdditionalAnswers
suggérée par David Wallace, mais peut être utile si vous souhaitez transformer l'argument "à la volée".la source
long
, cela peut-il encore fonctionner avec la boxe etLong.class
?J'ai eu un problème très similaire. L'objectif était de se moquer d'un service qui persiste sur les objets et peut les renvoyer par leur nom. Le service ressemble à ceci:
La maquette de service utilise une carte pour stocker les instances de salle.
Nous pouvons maintenant exécuter nos tests sur cette maquette. Par exemple:
la source
Avec Java 8, la réponse de Steve peut devenir
EDIT: Encore plus court:
la source
C'est une question assez ancienne mais je pense qu'elle est toujours d'actualité. De plus, la réponse acceptée ne fonctionne que pour String. En attendant, il y a Mockito 2.1 et certaines importations ont changé, je voudrais donc partager ma réponse actuelle:
La fonction myClass.myFunction ressemblerait à:
la source
J'utilise quelque chose de similaire (en gros c'est la même approche). Parfois, il est utile qu'un objet simulé renvoie une sortie prédéfinie pour certaines entrées. Cela se passe comme ceci:
la source
Vous souhaiterez peut-être utiliser verify () en combinaison avec ArgumentCaptor pour assurer l'exécution dans le test et ArgumentCaptor pour évaluer les arguments:
La valeur de l'argument est évidemment accessible via l'argument.getValue () pour une manipulation / vérification / autre.
la source
C'est un peu vieux, mais je suis venu ici parce que j'avais le même problème. J'utilise JUnit mais cette fois dans une application Kotlin avec mockk. Je poste un échantillon ici pour référence et comparaison avec l'homologue Java:
la source
Vous pouvez y parvenir en utilisant ArgumentCaptor
Imaginez que vous ayez une fonction de bean comme ça.
Ensuite, dans votre classe de test:
OU si vous êtes fan de lambda, faites simplement:
Résumé: utilisez argumentcaptor pour capturer le paramètre transmis. Plus tard dans la réponse, renvoyez la valeur capturée à l'aide de getValue.
la source
This doesn´t work (anymore?).
je travaille sur mon instance. 2. Désolé, je ne suis pas clair sur le point que vous essayez de faire valoir. La réponse est spécifique à la question d'OP.