J'utilise Mockito pour le service après-vente des tests unitaires. Je suis confus quand utiliser doAnswer
vs thenReturn
.
Quelqu'un peut-il m'aider en détail? Jusqu'ici, je l'ai essayé avec thenReturn
.
Vous devez utiliser thenReturn
ou doReturn
lorsque vous connaissez la valeur de retour au moment où vous vous moquez d'un appel de méthode. Cette valeur définie est renvoyée lorsque vous appelez la méthode simulée.
thenReturn(T value)
Définit une valeur de retour à renvoyer lorsque la méthode est appelée.
@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
est utilisé lorsque vous devez effectuer des actions supplémentaires lorsqu'une méthode simulée est appelée, par exemple. lorsque vous devez calculer la valeur de retour en fonction des paramètres de cet appel de méthode.
Utilisez
doAnswer()
lorsque vous souhaitez remplacer une méthode void avec le génériqueAnswer
.La réponse spécifie une action qui est exécutée et une valeur de retour qui est renvoyée lorsque vous interagissez avec le mock.
@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");
}
doAnswer
et thenReturn
font la même chose si:
Raillons ce BookService
public interface BookService {
String getAuthor();
void queryBookTitle(BookServiceCallback callback);
}
Vous pouvez bloquer getAuthor () en utilisant doAnswer
et 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();
Notez que lorsque vous utilisez doAnswer
, vous ne pouvez pas transmettre de méthode à when
.
// Will throw UnfinishedStubbingException
doAnswer(invocation -> "Joshua").when(service.getAuthor());
Alors, quand utiliseriez-vous doAnswer
au lieu de thenReturn
? Je peux penser à deux cas d'utilisation:
En utilisant doAnswer, vous pouvez effectuer certaines actions supplémentaires lors de l’appel de la méthode. Par exemple, déclencher un rappel sur queryBookTitle.
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);
Lors de l’utilisation de when-thenReturn on, Spy Mockito appellera méthode réelle puis stub votre réponse. Cela peut poser un problème si vous ne souhaitez pas appeler une méthode réelle, comme dans cet exemple:
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));
En utilisant doAnswer, nous pouvons le remplacer en toute sécurité.
List list = new LinkedList();
List spy = spy(list);
doAnswer(invocation -> "Java").when(spy).get(0);
assertEquals("Java", spy.get(0));
En fait, si vous ne souhaitez pas effectuer d'actions supplémentaires lors de l'appel de la méthode, vous pouvez simplement utiliser doReturn
.
List list = new LinkedList();
List spy = spy(list);
doReturn("Java").when(spy).get(0);
assertEquals("Java", spy.get(0));