Mockito: doAnswer vs thenReturn

I am using Mockito for service later unit testing. I am confused when to use doAnswer vs thenReturn.

Can anyone help me in detail? So far, I have tried it with thenReturn.

3 Answers

You should use thenReturn or doReturn when you know the return value at the time you mock a method call. This defined value is returned when you invoke the mocked method.

thenReturn(T value) Sets a return value to be returned when the method is called.

@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 is used when you need to do additional actions when a mocked method is invoked, e.g. when you need to compute the return value based on the parameters of this method call.

Use doAnswer() when you want to stub a void method with generic Answer.

Answer specifies an action that is executed and a return value that is returned when you interact with the 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");
}
5

doAnswer and thenReturn do the same thing if:

  1. You are using Mock, not Spy
  2. The method you're stubbing is returning a value, not a void method.

Let's mock this BookService

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

You can stub getAuthor() using doAnswer and 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();

Note that when using doAnswer, you can't pass a method on when.

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

So, when would you use doAnswer instead of thenReturn? I can think of two use cases:

  1. When you want to "stub" void method.

Using doAnswer you can do some additionals actions upon method invocation. For example, trigger a callback on 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. When you are using Spy instead of Mock

When using when-thenReturn on Spy Mockito will call real method and then stub your answer. This can cause a problem if you don't want to call real method, like in this sample:

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));

Using doAnswer we can stub it safely.

List list = new LinkedList();
List spy = spy(list);
doAnswer(invocation -> "java").when(spy).get(0);
assertEquals("java", spy.get(0));

Actually, if you don't want to do additional actions upon method invocation, you can just use doReturn.

List list = new LinkedList();
List spy = spy(list);
doReturn("java").when(spy).get(0);
assertEquals("java", spy.get(0));
3

The simplest answer is:

  • If you need a fixed return value on method call then we should use thenReturn(…)
  • If you need to perform some operation or the value need to be computed at run time then we should use thenAnswer(…)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Alexander Ross

Alexander Ross

Gaming, Esports & Interactive Media Writer

Alexander Ross has covered the video game industry for a decade, writing deep dives on game design, esports tournaments, VR developments, and gaming culture.

Share this article
Twitter Facebook Pinterest