Ok, wie wäre es mit einem Java-Mocking-Framework im Allgemeinen ... Ist dies mit jedem anderen Framework möglich, oder sollte ich einfach einen dummen Stub erstellen, um das gewünschte Verhalten nachzuahmen?
Abhijeet Kashnia
Antworten:
1000
Sie können eine Antwort in Mockito erstellen. Nehmen wir an, wir haben eine Schnittstelle namens Application mit der Methode myFunction.
Das habe ich auch gesucht. Vielen Dank! Mein Problem war jedoch anders. Ich möchte einen Persistenzdienst (EJB) verspotten, der Objekte speichert und sie nach Namen zurückgibt.
Migu
7
Ich habe eine zusätzliche Klasse erstellt, die die Erstellung der Antwort umschließt. Der Code lautet also wie when(...).then(Return.firstParameter())
folgt:
69
Mit Java 8 Lambdas ist es einfach, das erste Argument zurückzugeben, selbst für eine bestimmte Klasse, d when(foo(any()).then(i -> i.getArgumentAt(0, Bar.class)). H. Sie können auch eine Methodenreferenz verwenden und eine echte Methode aufrufen.
Paweł Dyda
Dies löst mein Problem mit einer Methode, die Iterator<? extends ClassName>alle Arten von Cast-Problemen in einer thenReturn()Anweisung verursacht.
Michael Shopsin
16
Mit Java 8 und Mockito <1.9.5 wird Pawełs Antwortwhen(foo(any()).thenAnswer(i -> i.getArguments()[0])
Graeme Moss
565
Wenn Sie Mockito 1.9.5 oder höher haben, gibt es eine neue statische Methode, mit der AnswerSie das Objekt für Sie erstellen können . Sie müssen so etwas schreiben
Beachten Sie, dass die returnsFirstArg()Methode in der AdditionalAnswersKlasse statisch ist , die für Mockito 1.9.5 neu ist. Sie benötigen also den richtigen statischen Import.
Hinweis: Es ist when(...).then(returnsFirstArg()), ich hatte fälschlicherweise, when(...).thenReturn(returnsFirstArg())was gabjava.lang.ClassCastException: org.mockito.internal.stubbing.answers.ReturnsArgumentAt cannot be cast to
Benedikt Köppel
1
Hinweis: returnFirstArg () gibt Antwort <> und nicht den Wert des Arguments zurück. Beim Versuch, .thenReturn (new Foo (returnFirstArg ()))
Lu55
Ich muss diese Antwort in den letzten Jahren immer wieder googeln, da ich mich einfach nicht an "AdditionalAnswers" erinnern kann und sie nur sehr selten brauche. Dann frage ich mich, wie zum Teufel ich dieses Szenario aufbauen kann, da ich die notwendigen Abhängigkeiten nicht finden kann. Könnte dies nicht einfach direkt zu mockito hinzugefügt werden? : /
BAERUS
2
Steves Antwort ist allgemeiner. In diesem Fall können Sie nur das Rohargument zurückgeben. Wenn Sie dieses Argument verarbeiten und das Ergebnis zurückgeben möchten, gelten die Antwortregeln von Steve. Ich habe beide positiv bewertet, da beide nützlich sind.
Akostadinov
Zu Ihrer Information, wir müssen importieren static org.mockito.AdditionalAnswers.returnsFirstArg. Dies wird verwendet, um returnFirstArg zu verwenden. Auch kann ich when(myMock.myFunction(any())).then(returnsFirstArg())in Mockito 2.20 tun . *
gtiwari333
77
Mit Java 8 ist es möglich, auch mit einer älteren Version von Mockito eine einzeilige Antwort zu erstellen:
Dies ist natürlich nicht so nützlich wie die AdditionalAnswersvon David Wallace vorgeschlagene, kann aber nützlich sein, wenn Sie das Argument "on the fly" transformieren möchten.
Brillant. Vielen Dank. Wenn das Argument ist long, kann dies immer noch mit Boxen und funktionieren Long.class?
Wikingersteve
1
.getArgumentAt (..) wurde nicht für mich gefunden, aber .getArgument (1) hat funktioniert (mockito 2.6.2)
Curtis Yallop
41
Ich hatte ein sehr ähnliches Problem. Das Ziel war es, einen Dienst zu verspotten, der Objekte beibehält und sie mit ihrem Namen zurückgeben kann. Der Service sieht folgendermaßen aus:
Dies ist eine ziemlich alte Frage, aber ich denke immer noch relevant. Auch die akzeptierte Antwort funktioniert nur für String. Inzwischen gibt es Mockito 2.1 und einige Importe haben sich geändert, daher möchte ich meine aktuelle Antwort teilen:
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());
Die myClass.myFunction würde folgendermaßen aussehen:
Ich benutze etwas Ähnliches (im Grunde ist es der gleiche Ansatz). Manchmal ist es nützlich, wenn ein Scheinobjekt für bestimmte Eingaben eine vordefinierte Ausgabe zurückgibt. Das geht so:
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}}});
Möglicherweise möchten Sie verify () in Kombination mit dem ArgumentCaptor verwenden, um die Ausführung im Test sicherzustellen, und dem ArgumentCaptor, um die Argumente auszuwerten:
ArgumentCaptor<String> argument =ArgumentCaptor.forClass(String.class);
verify(mock).myFunction(argument.capture());
assertEquals("the expected value here", argument.getValue());
Der Wert des Arguments ist offensichtlich über argument.getValue () für weitere Manipulationen / Überprüfungen / was auch immer zugänglich.
Das ist ein bisschen alt, aber ich bin hierher gekommen, weil ich das gleiche Problem hatte. Ich benutze JUnit aber diesmal in einer Kotlin App mit Mockk. Ich poste hier ein Beispiel als Referenz und Vergleich mit dem Java-Gegenstück:
@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.}});
ODER wenn Sie Lambda-Fan sind, tun Sie einfach:
//Use ArgumentCaptor to capture the valueArgumentCaptor<String> param =ArgumentCaptor.forClass(String.class);
when(mock.myFunction(param.capture())).thenAnswer((invocation)-> param.getValue());
Zusammenfassung: Verwenden Sie argumentcaptor, um den übergebenen Parameter zu erfassen. Geben Sie später in der Antwort den mit getValue erfassten Wert zurück.
Das funktioniert nicht mehr (?). In Bezug auf die Dokumente: Diese Methode muss innerhalb der Überprüfung verwendet werden. Das heißt, Sie können den Wert nur erfassen, wenn Sie die Überprüfungsmethode verwenden
Muhammed Misir
1. This doesn´t work (anymore?).Ich bin mir nicht sicher, was du damit meinst. Ich arbeite an meiner Instanz. 2. Entschuldigung, ich bin mir nicht sicher, welchen Punkt Sie anstreben. Die Antwort ist spezifisch für die Frage von OP.
Antworten:
Sie können eine Antwort in Mockito erstellen. Nehmen wir an, wir haben eine Schnittstelle namens Application mit der Methode myFunction.
Hier ist die Testmethode mit einer Mockito-Antwort:
Seit Mockito 1.9.5 und Java 8 können Sie auch einen Lambda-Ausdruck verwenden:
quelle
when(...).then(Return.firstParameter())
when(foo(any()).then(i -> i.getArgumentAt(0, Bar.class))
. H. Sie können auch eine Methodenreferenz verwenden und eine echte Methode aufrufen.Iterator<? extends ClassName>
alle Arten von Cast-Problemen in einerthenReturn()
Anweisung verursacht.when(foo(any()).thenAnswer(i -> i.getArguments()[0])
Wenn Sie Mockito 1.9.5 oder höher haben, gibt es eine neue statische Methode, mit der
Answer
Sie das Objekt für Sie erstellen können . Sie müssen so etwas schreibenoder alternativ
Beachten Sie, dass die
returnsFirstArg()
Methode in derAdditionalAnswers
Klasse statisch ist , die für Mockito 1.9.5 neu ist. Sie benötigen also den richtigen statischen Import.quelle
when(...).then(returnsFirstArg())
, ich hatte fälschlicherweise,when(...).thenReturn(returnsFirstArg())
was gabjava.lang.ClassCastException: org.mockito.internal.stubbing.answers.ReturnsArgumentAt cannot be cast to
static org.mockito.AdditionalAnswers.returnsFirstArg
. Dies wird verwendet, um returnFirstArg zu verwenden. Auch kann ichwhen(myMock.myFunction(any())).then(returnsFirstArg())
in Mockito 2.20 tun . *Mit Java 8 ist es möglich, auch mit einer älteren Version von Mockito eine einzeilige Antwort zu erstellen:
Dies ist natürlich nicht so nützlich wie die
AdditionalAnswers
von David Wallace vorgeschlagene, kann aber nützlich sein, wenn Sie das Argument "on the fly" transformieren möchten.quelle
long
, kann dies immer noch mit Boxen und funktionierenLong.class
?Ich hatte ein sehr ähnliches Problem. Das Ziel war es, einen Dienst zu verspotten, der Objekte beibehält und sie mit ihrem Namen zurückgeben kann. Der Service sieht folgendermaßen aus:
Der Service-Mock verwendet eine Karte zum Speichern der Rauminstanzen.
Wir können jetzt unsere Tests mit diesem Modell durchführen. Zum Beispiel:
quelle
Mit Java 8 kann Steves Antwort werden
EDIT: Noch kürzer:
quelle
Dies ist eine ziemlich alte Frage, aber ich denke immer noch relevant. Auch die akzeptierte Antwort funktioniert nur für String. Inzwischen gibt es Mockito 2.1 und einige Importe haben sich geändert, daher möchte ich meine aktuelle Antwort teilen:
Die myClass.myFunction würde folgendermaßen aussehen:
quelle
Ich benutze etwas Ähnliches (im Grunde ist es der gleiche Ansatz). Manchmal ist es nützlich, wenn ein Scheinobjekt für bestimmte Eingaben eine vordefinierte Ausgabe zurückgibt. Das geht so:
quelle
Möglicherweise möchten Sie verify () in Kombination mit dem ArgumentCaptor verwenden, um die Ausführung im Test sicherzustellen, und dem ArgumentCaptor, um die Argumente auszuwerten:
Der Wert des Arguments ist offensichtlich über argument.getValue () für weitere Manipulationen / Überprüfungen / was auch immer zugänglich.
quelle
Das ist ein bisschen alt, aber ich bin hierher gekommen, weil ich das gleiche Problem hatte. Ich benutze JUnit aber diesmal in einer Kotlin App mit Mockk. Ich poste hier ein Beispiel als Referenz und Vergleich mit dem Java-Gegenstück:
quelle
Sie können dies mit ArgumentCaptor erreichen
Stellen Sie sich vor, Sie haben eine solche Bohnenfunktion.
Dann in Ihrer Testklasse:
ODER wenn Sie Lambda-Fan sind, tun Sie einfach:
Zusammenfassung: Verwenden Sie argumentcaptor, um den übergebenen Parameter zu erfassen. Geben Sie später in der Antwort den mit getValue erfassten Wert zurück.
quelle
This doesn´t work (anymore?).
Ich bin mir nicht sicher, was du damit meinst. Ich arbeite an meiner Instanz. 2. Entschuldigung, ich bin mir nicht sicher, welchen Punkt Sie anstreben. Die Antwort ist spezifisch für die Frage von OP.