A dive into Mockito – 3


Part 3 - Partial Mocks using Mockito and Limitations of Mockito

  • Partial Mocks – with mocks and spies
  • Create a mock of the class
  • Spy the class
  • Which method to use – mock or spy?
  • Limitations of Mockito

Full Series


Partial Mocks – with mocks and spies

Partial mocks are created when only some methods of a class need to be stubbed, and the real methods must be called for others.

Partial mocks can be created in two ways:

  1. Create a mock of the class
    This would create mock implementation of all the methods. For calling the real method, we must use thenCallRealMethod()
  2. Spy the class
    This is the opposite of creating mocks. This will call real methods, unless otherwise specified by stubs.

Let us consider EmailManager.java having a method: String getEmail(String name)


Create a mock of the class

Partial mocks can be created in the following manner by creating mocks:

EmailManager managerMock = Mockito.mock(EmailManager.class);
Mockito.when(managerMock.getEmail(Mockito.anyString())).thenCallRealMethod();

This will call the real implementation of getEmail() method in the EmailManager. The mock implementations will be called for all other methods.

Spy the class

This is the method to create spies of real objects:

EmailManager manager = new EmailManager();
EmailManager managerSpy = Mockito.spy(manager);
Mockito.when(managerSpy.getEmail(Mockito.anyString())).thenReturn("abc@xyz.com");

This will call the stubbed implementation of getEmail() method in the EmailManager. The real implementation will be called for all other methods

Exception when spying:

While spying, remember that the actual methods are called. This can cause a lot of side effects, and sometimes Exceptions.

The primary reason for this is that the method call inside when() actually gets executed. So, even if the method is stubbed, it can internally call another method of the class which might not be stubbed, and the real method will be called.

The below code would fail:

List list = new LinkedList();
List spy = Mockito.spy(list);
Mockito.when(spy.get(0)).thenReturn("foo");

A closer look at the stacktrace shows something like this:

Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
  at java.util.LinkedList.entry(LinkedList.java:368)
  at java.util.LinkedList.get(LinkedList.java:313)
  ...

The get(0) internally calls entry() method(), which is not stubbed, causing the real method to be called.

To prevent this error, an alternative syntax must be used:

Mockito.doReturn("foo").when(spy).get(0);

Which method to use – mock or spy?

To decide which method to use, take a look at how many methods need to be stubbed.

  • If more real methods need to be called, then use spy.
  • Otherwise, use mock

New, well-designed and test-driven code should not use partial mocks. Using partial mocks means that the actual code is badly designed. But that should not stop us from writing unit tests.

A bad unit test is better than no unit test.


Limitations of Mockito

Mockito has a few limitations

  • Cannot mock final classes
  • Cannot mock static methods
  • Cannot mock final methods – their real behaviour is executed without any exception. Mockito cannot warn you about mocking final methods, so be vigilant.
  • Cannot mock equals(), hashCode()

Future articles in the series:

  • Part 4 – Some complex examples and common mistakes in using Mockito