What are the use cases for doReturn(), doThrow(), and doAnswer() in Mockito?

doReturn(), doThrow(), and doAnswer() are Mockito's alternative stubbing syntax, used when when()...then...() doesn't apply cleanly, such as for void methods or spies.

Key Points: • doReturn(value).when(mock).method() sets a return value without invoking the real method first, which matters for spies. • doThrow(exception).when(mock).method() makes the call throw, and works for both void and non-void methods. • doAnswer(invocation -> {...}).when(mock).method() lets you compute a return value dynamically or inspect/mutate the arguments passed. • On a spy, when(spy.method()) would actually execute the real method before stubbing it, which doReturn() avoids. • doAnswer() is the most flexible of the three and is often used to simulate side effects like modifying an output parameter.

Example: On a spy over a real ArrayList, doReturn(999).when(spyList).size() overrides size() without triggering any real list logic during stubbing.

Code Example:

List<String> spyList = spy(new ArrayList<>());
doReturn(999).when(spyList).size();

doAnswer(invocation -> {
    String arg = invocation.getArgument(0);
    return arg.toUpperCase();
}).when(mockService).transform(anyString());

Interview Tip: A concise interview answer is:

"doReturn(), doThrow(), and doAnswer() are the do-family stubbing methods I use for void calls, spies, or when I need dynamic behavior based on the arguments passed in. doReturn() avoids invoking the real method on a spy, and doAnswer() gives full control to compute a result or trigger a side effect."