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."