There are several disadvantages to the when/thenReturn
, when/thenThrow
and when/then
syntaxes. For example,
- In the case of
when/thenReturn
, if the return type is a generic with a
wildcard, and you wish to return a mock of the same type, you will be unable
to avoid a compile warning. - You can’t use
when/thenThrow
andwhen/then
for a void method. - You can’t use these syntaxes on Mockito spies.
- You can only call
when
once for each combination of mock object,
method and arguments, unless you callreset
on the mock. - Calling
when
multiple times for one combination of mock
object and method, when you are using argument matchers, can lead to problems.
I find these cases difficult to remember. So instead of trying to keep track of when the
when/thenReturn
, when/thenThrow
and when/then
syntaxes will and won’t work, I prefer to avoid them completely, in favour of the doReturn/when
, doThrow/when
and doAnswer/when
alternatives. That is to say, since you’ll occasionally need doReturn/when
, doThrow/when
and doAnswer/when
, and you can ALWAYS use these methods, there is no point in learning how to use when/thenReturn
, when/thenThrow
and when/then
.
Note that doReturn
, doThrow
and doAnswer
can be chained together in the same way as thenReturn
, thenThrow
and then
. What they don’t have is an option for returning several values (or throwing several exceptions, or running several answers) within a single call to doReturn
, doThrow
and doAnswer
. But I find that I need to do this so seldom, that it doesn’t really matter.
There’s one more disadvantage to doReturn
, which I consider insignificant. You don’t get compile time checking of the type of its argument, like you do with when/thenReturn
. So if you get the argument type wrong, you won’t find out until you run your test. Frankly, I don’t care.
In summary then, I have been using Mockito for more than two years, and I consider the consistent use of doReturn
, doThrow
and doAnswer
to be a Mockito best practice. Other Mockito users disagree.