I am currently using Mockito doReturn () to mock my service layer objects in a Spring MVC application for testing my controller methods.
I have observed that doReturn(…).when(…) is functionally equivalent to when(…).thenReturn(…). My question is, what is the purpose of having two methods that perform the same task, or is there a subtle difference between them?
I am specifically looking to understand the distinction between these two approaches in Mockito and their use cases.
Thanks!
The two approaches in Mockito, doReturn(...).when(...)
and when(...).thenReturn(...)
, behave differently when dealing with spied objects (annotated with @Spy
) versus mocks (annotated with @Mock
).
-
when(...).thenReturn(...)
:
This method invokes the real method before returning the mocked value. So, if the real method throws an exception, you must handle or mock it accordingly. The actual method execution can influence the outcome of your test.
public class MyClass {
protected String methodToBeTested() {
return anotherMethodInClass();
}
protected String anotherMethodInClass() {
throw new NullPointerException();
}
}
Test:
@Spy
private MyClass myClass;
// This will throw a NullPointerException
when(myClass.anotherMethodInClass()).thenReturn("test");
doReturn(...).when(...)
:
This approach bypasses the real method call and directly returns the mocked value. It is useful when you want to avoid exceptions that might be thrown by the real method or when you need to mock the method’s behavior without executing it.
Example:
@Spy
private MyClass myClass;
// This works fine and avoids calling the real method
doReturn("test").when(myClass).anotherMethodInClass();
Summary:
Use doReturn(...).when(...)
when you need to avoid invoking the real method—particularly when the method might throw an exception or when you simply want to mock the behavior without executing it.
The two syntaxes for stubbing in Mockito, when(…).thenReturn(…) and doReturn(…).when(…), are roughly equivalent in functionality. However, there are specific scenarios where doReturn(…).when(…) is preferable:
-
Void Methods: You can only stub void methods using doReturn(…).when(…). The when(…).thenReturn(…) syntax does not work for void methods.
-
Mockito Spies: When working with Mockito spies, doReturn(…).when(…) is required because when(…).thenReturn(…) will invoke the real method, which may not be desirable.
-
Stubbing the Same Method Multiple Times: doReturn(…).when(…) is more flexible when stubbing a method multiple times with different behaviors.
One advantage of when(…).thenReturn(…) is that it provides compile-time type-checking for the return value. However, this type-checking is of limited value because you typically discover type errors during test execution anyway.
For simplicity and consistency, it is recommended to use doReturn(…).when(…) exclusively. Learning and using just one syntax avoids confusion and is generally sufficient for all stubbing needs.
Just a quick heads-up—
Mockito generally recommends using
when(...).thenReturn(...)
over doReturn(...).when(...)
. It’s seen as the cleaner, more standard approach in most cases.
That said, I’ve found doReturn(...).when(...)
can still come in handy for those edge cases where you need to avoid calling the actual method.
But whenever possible, sticking with when(...).thenReturn(...)
keeps your tests a bit more in line with best practices!