Mockito - difference between doReturn() and when()

JavaUnit TestingMockito

Java Problem Overview


I am currently in the process of using Mockito to mock my service layer objects in a Spring MVC application in which I want to test my Controller methods. However, as I have been reading on the specifics of Mockito, I have found that the methods doReturn(...).when(...) is equivalent to when(...).thenReturn(...). So, my question is what is the point of having two methods that do the same thing or what is the subtle difference between doReturn(...).when(...) and when(...).thenReturn(...)?

Any help would be appreciated.

Java Solutions


Solution 1 - Java

The two syntaxes for stubbing are roughly equivalent. However, you can always use doReturn/when for stubbing; but there are cases where you can't use when/thenReturn. Stubbing void methods is one such. Others include use with Mockito spies, and stubbing the same method more than once.

One thing that when/thenReturn gives you, that doReturn/when doesn't, is type-checking of the value that you're returning, at compile time. However, I believe this is of almost no value - if you've got the type wrong, you'll find out as soon as you run your test.

I strongly recommend only using doReturn/when. There is no point in learning two syntaxes when one will do.

You may wish to refer to my answer at https://stackoverflow.com/questions/11462697/forming-mockito-grammars - a more detailed answer to a very closely related question.

Solution 2 - Java

Both approaches behave differently if you use a spied object (annotated with @Spy) instead of a mock (annotated with @Mock):

  • when(...) thenReturn(...) makes a real method call just before the specified value will be returned. So if the called method throws an Exception you have to deal with it / mock it etc. Of course you still get your result (what you define in thenReturn(...))

  • doReturn(...) when(...) does not call the method at all.

Example:

public class MyClass {
     protected String methodToBeTested() {
           return anotherMethodInClass();
     }

     protected String anotherMethodInClass() {
          throw new NullPointerException();
     }
}

Test:

@Spy
private MyClass myClass;

// ...

// would work fine
doReturn("test").when(myClass).anotherMethodInClass();

// would throw a NullPointerException
when(myClass.anotherMethodInClass()).thenReturn("test");

Solution 3 - Java

The Mockito javadoc seems to tell why use doReturn() instead of when() Use doReturn() in those rare occasions when you cannot use Mockito.when(Object).

> Beware that Mockito.when(Object) is always recommended for stubbing > because it is argument type-safe and more readable (especially when > stubbing consecutive calls). > > Here are those rare occasions when doReturn() comes handy: > > > 1. When spying real objects and calling real methods on a spy brings side > effects > > List list = new LinkedList(); List spy = spy(list); > > //Impossible: real method is called so spy.get(0) throws > IndexOutOfBoundsException (the list is yet empty) > > when(spy.get(0)).thenReturn("foo"); > > //You have to use doReturn() for stubbing: > doReturn("foo").when(spy).get(0); > >2. Overriding a previous exception-stubbing: > > when(mock.foo()).thenThrow(new RuntimeException()); > > //Impossible: the exception-stubbed foo() method is called so > RuntimeException is thrown. when(mock.foo()).thenReturn("bar"); > > //You have to use doReturn() for stubbing: > > doReturn("bar").when(mock).foo(); Above scenarios shows a tradeoff > of Mockito's elegant syntax. Note that the scenarios are very rare, > though. Spying should be sporadic and overriding exception-stubbing is > very rare. Not to mention that in general overridding stubbing is a > potential code smell that points out too much stubbing.

Solution 4 - Java

Continuing this answer, There is another difference that if you want your method to return different values for example when it is first time called, second time called etc then you can pass values so for example...

PowerMockito.doReturn(false, false, true).when(SomeClass.class, "SomeMethod", Matchers.any(SomeClass.class));

So it will return false when the method is called in same test case and then it will return false again and lastly true.

Solution 5 - Java

The latter alternative is used for methods on mocks that return void.

Please have a look, for example, here: https://stackoverflow.com/questions/2276271/how-to-make-mock-to-void-methods-with-mockito

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionblackpantherView Question on Stackoverflow
Solution 1 - JavaDawood ibn KareemView Answer on Stackoverflow
Solution 2 - JavaakcasoyView Answer on Stackoverflow
Solution 3 - Javauser2493028View Answer on Stackoverflow
Solution 4 - JavaAZ_View Answer on Stackoverflow
Solution 5 - JavavikingsteveView Answer on Stackoverflow