J'utilise Mockito pour les tests unitaires ultérieurs. Je suis confus quand utiliser doAnswer
vs thenReturn
.
Quelqu'un peut-il m'aider en détail? Jusqu'à présent, je l'ai essayé avec thenReturn
.
J'utilise Mockito pour les tests unitaires ultérieurs. Je suis confus quand utiliser doAnswer
vs thenReturn
.
Quelqu'un peut-il m'aider en détail? Jusqu'à présent, je l'ai essayé avec thenReturn
.
Réponses:
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 invoquée, par exemple lorsque vous devez calculer la valeur de retour basée sur les paramètres de cet appel de méthode.
À utiliser
doAnswer()
lorsque vous souhaitez stuber une méthode void avec genericAnswer
.Réponse spécifie une action qui est exécutée et une valeur de retour qui est renvoyée lorsque vous interagissez avec la maquette.
@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");
}
Answer
juste avec return UUID.randomUUID();
.
Answer
est une interface fonctionnelle, donc avec Java 8, vous pouvez la remplacer par une expression lambda. Si le n'est pas assez propre, tout autre refactoring habituel et inhabituel est possible.
doAnswer
et thenReturn
faites la même chose si:
Moquons-nous de ce BookService
public interface BookService {
String getAuthor();
void queryBookTitle(BookServiceCallback callback);
}
Vous pouvez stub 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 lors de l'utilisation doAnswer
, vous ne pouvez pas transmettre une méthode when
.
// Will throw UnfinishedStubbingException
doAnswer(invocation -> "Joshua").when(service.getAuthor());
Alors, quand utiliseriez-vous à la doAnswer
place de thenReturn
? Je peux penser à deux cas d'utilisation:
En utilisant doAnswer, vous pouvez effectuer des actions supplémentaires lors de l'appel de méthode. Par exemple, déclenchez 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);
Lorsque vous utilisez when-thenReturn on Spy Mockito appellera la méthode réelle, puis stub votre réponse. Cela peut poser un problème si vous ne souhaitez pas appeler de 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 stuber 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 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));
doAnswer(new Answer() { ... return null;}
j'obtiens un avertissement dans eclipse pour "La réponse est un type brut. Les références au type générique Answer <T> doivent être paramétrées". Existe-t-il un moyen de résoudre ce problème (sauf en ignorant l'avertissement ofc)?
code = UUID.randomUUID()
, j'ai trouvé impossible de l'implémenter avecmockito
.