Create mocks with mockito

This is a small summarization what the differences are between the different variations creating mocks with mockito.

Null values (default)

Per default, after creating a mock, every method will return null. Just create your mock with:

Sample sample = Mockito.mock(ISample.class);

I think, this is very useful and straight forward. (And based by mockito developers idea, to create very fast a mock for testing). Sometimes it is very difficult to determine an error which was produced through such a null value. For this case it is very practicable to tell mockito, returning SmartNullValues.

Smart null values

By using SmartNullValues, you will receive a stack trace which tells you, where the NullPointer was thrown and which mock object returned the SmartNullValue.
Just create a mock with:

Sample sample = Mockito.mock(ISample.class, RETURNS_SMART_NULLS);

I will explain the difference between the smart null values and the default values with the following stack traces. The following code will show you how to produce the NullPointer.

public class SNPETest {
   @Test
   public void testSmartNPE() throws Exception {
      Writer wr = mock(Writer.class, RETURNS_SMART_NULLS);
      doSomething(wr);
   }

   void doSomething(Writer wr) throws Exception {
      Writer wr2 = wr.append('a');
      wr2.append('b');
   }

   @Test
   public void testNPE() throws Exception {
      Writer wr = mock(Writer.class);
      doSomething(wr);
   }

}
testSmartNPE(test.SNPETest)
org.mockito.exceptions.verification.SmartNullPointerException:
You have a NullPointerException here:
-> at test.SNPETest.doSomething(SNPETest.java:23)
Because this method was *not* stubbed correctly:
-> at test.SNPETest.doSomething(SNPETest.java:22)

        at test.SNPETest.doSomething(SNPETest.java:23)
        at test.SNPETest.testSmartNPE(SNPETest.java:18)

testNPE(test.SNPETest)
java.lang.NullPointerException
        at test.SNPETest.doSomething(SNPETest.java:23)
        at test.SNPETest.testNPE(SNPETest.java:29)

BUT, there is at least one disadvantage. If you have conditions that check for null, you have to stub the method and tell mockito to return null for this method.

Mocks

RETURNS_MOCKS and RETURNS_DEEP_STUBS is very similar. If you want to receive another mock by calling a method RETURNS_MOCKS is suitable.

Sample sample = Mockito.mock(ISample.class, RETURNS_MOCKS);

Every method on the mocked object will return another mock. OK OK, your right, not every method, there are some limitations. There are NO mocks returned on final methods. AND there are NO mocks on methods they return an object with a final class. The final methods you cant mock with default mockito. If you have a method which returns an object with a final class you have to stub it yourself.

Deep Stubs

And now you know whats going on with your mock if you do:

Sample sample = Mockito.mock(ISample.class, RETURNS_DEEP_STUBS);

right! If you get a chain of mocks. RETURNS_MOCKS stops mocking after one level. RETURNS_DEEP_STUBS goes deeper. If you call a method you receive a mock and if you call a method on this mock you receive a mock and … so on. There are the same limitations as they are on RETURNS_MOCKS. -> No final methods and no final classes as return values.
This is one of the newest variants creating mocks. Major problem is, if no stubbing is done, there will never returned null.

Mocking with annotation

If you need a mock without any logic or you don’t want always call Mockito.mock(ISample.class) there is also a possibility to create mock objects with annotations.

It works very simple. Just add the annotation @Mock to the member declaration and call MockitoAnnotations.initMocks(this); before tests. (this is in this case the test 😉 )

At the moment it does not look as there is a possibility to set SMART_NULLS or something like this with the annotations. Just run the test with MockitoJUnitRunner.

(All about the Mock interface you can find on www.mockito.org -> Documentation ;))

About the author

Adrian Elsener

Add comment

Recent Posts