In Mockito, you can specify what to return when a method is called. That makes unit testing easier because you don’t have to change existing classes. Mockito supports two ways to do it:
doReturn-when. In most cases,
when-thenReturn is used and has better readability.
However, sometimes you need to consider using
doReturn-when because there are different behaviors.
No type safety
The parameter of
thenReturn. So, there is no type checking in the compile time. When the type is mismatched in the runtime, there would be an
This is the main reason why
when-thenReturn is a better option if possible.
No side effect
Although there is no type safety, the advantage of
doReturn-when is no side effect. In Mockito, a side effect happens to the real method invocation. To understand this, you need to know when a real method invocation happens.
Generally, you first need to create a mock object with
Mockito.mock before specifying a return value. When you call a method of the mock object, it returns a specified value but it doesn’t do anything you defined in the class. There is no side effect so
doReturn-when acts almost the same except
when-thenReturn has a type safety.
The difference comes when you create a spy with
Mockito.spy. A spied object is linked to an actual object. So, there is a real method invocation when you call a method. This is valid even for when you do
when-thenReturn. This is due to a parameter of
when and it contains a way to invoke a method. e.g.
user.getName(). In contrast, a parameter of
when is only
user when you use
A side effect doesn’t happen always but here are the usual cases:
- A method throws an exception with precondition checking.
- A method does what you don’t want while unit testing. For example, network or disk access.
List#get() throws an exception if the list is smaller.
doReturn can specify a value without having an exception.
Another example is to change a class behavior for unit testing.
AccountService is a target to test so you cannot mock it. With
doNothing is for
void return type), you can do unit testing without network access.
If there is no side effect, you can still use
when-thenReturnfor a spied object.
You can use
doReturn-when to specify a return value on a spied object without making a side effect. It is useful but should be used rarely. The more you have a better pattern such as MVP, MVVM and dependency injection, the less chance you need to use
Mockito.spy. Then, you can use more type safe and readable