Ich verwende Mockito für spätere Einheitentests. Ich bin verwirrt, wann ich es verwenden soll doAnswer
vs thenReturn
.
Kann mir jemand im Detail helfen? Bisher habe ich es mit probiert thenReturn
.
Rajkumar Thambu
Ich verwende Mockito für spätere Einheitentests. Ich bin verwirrt, wann ich es verwenden soll doAnswer
vs thenReturn
.
Kann mir jemand im Detail helfen? Bisher habe ich es mit probiert thenReturn
.
Roland Wiesleder
Du solltest benutzen thenReturn
oder doReturn
wenn Sie den Rückgabewert kennen, wenn Sie einen Methodenaufruf simulieren. Dieser definierte Wert wird zurückgegeben, wenn Sie die simulierte Methode aufrufen.
thenReturn(T value)
Legt einen Rückgabewert fest, der zurückgegeben wird, wenn die Methode aufgerufen wird.
@Test
public void test_return() throws Exception {
Dummy dummy = mock(Dummy.class);
int returnValue = 5;
// choose your preferred way
when(dummy.stringLength("dummy")).thenReturn(returnValue);
doReturn(returnValue).when(dummy).stringLength("dummy");
}
Answer
wird verwendet, wenn Sie zusätzliche Aktionen ausführen müssen, wenn eine mockierte Methode aufgerufen wird, zB wenn Sie den Rückgabewert basierend auf den Parametern dieses Methodenaufrufs berechnen müssen.
Verwenden
doAnswer()
wenn Sie eine void-Methode mit generisch stubben möchtenAnswer
.Answer gibt eine Aktion an, die ausgeführt wird, und einen Rückgabewert, der zurückgegeben wird, wenn Sie mit dem Mock interagieren.
@Test
public void test_answer() throws Exception {
Dummy dummy = mock(Dummy.class);
Answer<Integer> answer = new Answer<Integer>() {
public Integer answer(InvocationOnMock invocation) throws Throwable {
String string = invocation.getArgumentAt(0, String.class);
return string.length() * 2;
}
};
// choose your preferred way
when(dummy.stringLength("dummy")).thenAnswer(answer);
doAnswer(answer).when(dummy).stringLength("dummy");
}
Hallo @Roland Weisleder, aber manchmal sollten Sie einen wertgenerierten inneren Code zurückgeben, der nichts mit Argumenten zu tun hat, z code = UUID.randomUUID()
fand ich unmöglich, dies mit umzusetzen mockito
.
– zhuguowei
5. September 2016 um 3:02 Uhr
Wenn Ihr Mock für jeden Aufruf eine neue UUID zurückgeben sollte, würden Sie die implementieren Answer
nur mit return UUID.randomUUID();
.
– Roland Weissleder
5. September 2016 um 9:07 Uhr
Kann ich diese Methode aus der neuen Answer-Initialisierung nehmen und sie in eine Methode einfügen, um den Code etwas sauberer zu machen?
– Linie
23. Mai 2017 um 10:24 Uhr
@Linie Answer
ist eine funktionale Schnittstelle, sodass Sie sie mit Java 8 durch einen Lambda-Ausdruck ersetzen könnten. Wenn das nicht sauber genug ist, ist jedes andere übliche und ungewöhnliche Refactoring möglich.
– Roland Weissleder
28. Mai 2017 um 16:17 Uhr
@ zhuguowei: Gibt einen wertgenerierten inneren Code zurück? Was meinst du damit?
– Saurabh Patil
30. November 2018 um 4:50 Uhr
aldok
doAnswer
und thenReturn
dasselbe tun, wenn:
Lassen Sie uns diesen BookService verspotten
public interface BookService {
String getAuthor();
void queryBookTitle(BookServiceCallback callback);
}
Sie können getAuthor() mit stubben doAnswer
und thenReturn
.
BookService service = mock(BookService.class);
when(service.getAuthor()).thenReturn("Joshua");
// or..
doAnswer(new Answer() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
return "Joshua";
}
}).when(service).getAuthor();
Beachten Sie dies bei der Verwendung doAnswer
können Sie keine Methode weitergeben when
.
// Will throw UnfinishedStubbingException
doAnswer(invocation -> "Joshua").when(service.getAuthor());
Also, wann würden Sie verwenden doAnswer
Anstatt von thenReturn
? Mir fallen zwei Anwendungsfälle ein:
Mit doAnswer können Sie einige zusätzliche Aktionen beim Methodenaufruf ausführen. Lösen Sie beispielsweise einen Rückruf für queryBookTitle aus.
BookServiceCallback callback = new BookServiceCallback() {
@Override
public void onSuccess(String bookTitle) {
assertEquals("Effective Java", bookTitle);
}
};
doAnswer(new Answer() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
BookServiceCallback callback = (BookServiceCallback) invocation.getArguments()[0];
callback.onSuccess("Effective Java");
// return null because queryBookTitle is void
return null;
}
}).when(service).queryBookTitle(callback);
service.queryBookTitle(callback);
Wenn Sie when-thenReturn auf Spy verwenden, ruft Mockito die echte Methode auf und stummt dann Ihre Antwort. Dies kann ein Problem verursachen, wenn Sie keine echte Methode aufrufen möchten, wie in diesem Beispiel:
List list = new LinkedList();
List spy = spy(list);
// Will throw java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
when(spy.get(0)).thenReturn("java");
assertEquals("java", spy.get(0));
Mit doAnswer können wir es sicher abbrechen.
List list = new LinkedList();
List spy = spy(list);
doAnswer(invocation -> "java").when(spy).get(0);
assertEquals("java", spy.get(0));
Wenn Sie beim Methodenaufruf keine zusätzlichen Aktionen ausführen möchten, können Sie einfach verwenden doReturn
.
List list = new LinkedList();
List spy = spy(list);
doReturn("java").when(spy).get(0);
assertEquals("java", spy.get(0));
Was ist, wenn die verspottete Methode ungültig ist?
– Igor Donin
4. Oktober 2018 um 16:47 Uhr
Igor, genau hier kommt doAnswer() ins Spiel und er hat das in der obigen Antwort behandelt.
– Saurabh Patil
30. November 2018 um 4:46 Uhr
Beim Benutzen doAnswer(new Answer() { ... return null;}
Ich erhalte eine Warnung in Eclipse für “Answer ist ein Rohtyp. Verweise auf den generischen Typ Answer
– LazR
28. Februar 2019 um 10:51 Uhr
Die einfachste Antwort lautet: