194 votes

Mockito: doAnswer Vs thenReturn

J'utilise Mockito pour le service après-vente des tests unitaires. Je ne sais plus trop quand utiliser doAnswer vs thenReturn .

Quelqu'un peut-il m'aider en détail? Jusqu'ici, j'ai essayé avec thenReturn .

241voto

Roland Weisleder Points 3203

Vous devez utiliser thenReturn ou doReturn quand vous savez que la valeur de retour au moment où vous vous moquez d'un appel de méthode. Cette valeur définie est renvoyé lorsque vous appelez la moqué de méthode.

thenReturn(T value) Définit une valeur de retour sera retourné 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 avez besoin pour faire des actions lorsqu'une moqué méthode est appelée, par exemple, lorsque vous avez besoin de calculer la valeur de retour sur la base des paramètres de l'appel de cette méthode.

Utiliser doAnswer() lorsque vous vous voulez talon un vide, une méthode générique de Answer.

La réponse indique une action qui est exécutée et une valeur de retour qui est renvoyé 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");
}

61voto

aldok Points 4348

doAnswer et thenReturn faire la même chose si:

  1. Vous êtes à l'aide de Maquette, pas de Spy
  2. La méthode que vous êtes stubbing est de retourner une valeur, pas une méthode void.

Nous allons se moquer de cette BookService

public interface BookService {
    String getAuthor();
    void queryBookTitle(BookServiceCallback callback);
}

Vous pouvez stub getAuthor() à l'aide d' 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 d' doAnswer, vous ne pouvez pas passer d'une méthode sur l' when.

// Will throw UnfinishedStubbingException
doAnswer(invocation -> "Joshua").when(service.getAuthor());

Donc, quand vous l'utiliser doAnswer au lieu de thenReturn? Je pense à deux cas d'utilisation:

  1. Quand vous voulez "stub" méthode void.

À l'aide de doAnswer vous pouvez faire un peu de additionels actions à prendre lors de l'invocation de 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);
  1. Lorsque vous utilisez Espion au lieu de se Moquer de

Lors de l'utilisation lors de l'-thenReturn sur Spy Mockito appellera véritable méthode, puis stub de votre réponse. Cela peut poser un problème si vous ne souhaitez pas appeler véritable méthode, 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));

À l'aide de doAnswer nous pouvons stub 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 voulez pas faire des actions supplémentaires lors de l'invocation 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));

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X