Creating Spies and Partial Mocks using Mockito

Mockito is a powerful mocking framework that simplifies the process of testing in Java. It allows the creation of mock objects that mimic the behavior of real objects, enabling developers to isolate the code under test and verify its interactions with other components. In addition to regular mocks, Mockito also provides the capability to create spies and partial mocks, which can be valuable in certain situations.

Spies

A spy is a special type of mock that allows you to wrap an existing object and selectively stub or verify some of its methods while keeping the original behavior for the rest. In other words, it allows you to partially mock a real object.

To create a spy using Mockito, you need to call the spy() method and pass the object you want to spy on as a parameter. For example, let's assume we have a class called UserService with a method getUserData() that we want to spy on:

UserService userService = new UserService();
UserService spyUserService = spy(userService);

With the spy object created, we can then stub or verify specific methods of the real object. For example, let's stub the getUserData() method to return a predefined value:

when(spyUserService.getUserData()).thenReturn(userData);

In this example, when the getUserData() method is called on the spy, it will return the userData value instead of executing the original implementation. However, all other methods of the UserService class will still behave as usual.

Partial Mocks

A partial mock is similar to a spy, but with the ability to mock only selected methods of an object while executing the original behavior for the rest. It is a way to create a real object with some methods mocked.

To create a partial mock, you can use the same approach as for creating a spy. Mocking only specific methods can be achieved using the doCallRealMethod() or doReturn() syntax. Let's illustrate this with an example:

UserService userService = new UserService();
UserService partialMockUserService = spy(userService);

doCallRealMethod().when(partialMockUserService).getUserData();

In this example, we're creating a partial mock of the UserService class, and we're stubbing the getUserData() method to call the real method of the object. This means that all other methods of the UserService class will behave as usual, while the getUserData() method will execute the real implementation.

You can also combine partial mocks with regular stubbing or verification of methods using Mockito's API.

Limitations

It's important to note that the partial mocking feature provided by Mockito has some limitations. It is generally recommended to favor refactoring the code to be more testable instead of relying heavily on partial mocks. Overusing spies and partial mocks can lead to test code that is hard to understand and maintain.

Conclusion

In this article, we explored the concept of spies and partial mocks in Mockito. Spies allow you to wrap an existing object and selectively stub or verify some of its methods while keeping the original behavior for the rest. Partial mocks, on the other hand, provide the ability to mock only selected methods of an object while executing the real behavior for the rest.

Both spies and partial mocks can be useful tools in certain testing scenarios. However, it's important to use them judiciously and ensure that they don't become a crutch for poor design or hard-to-test code. Mockito offers a powerful set of features for creating mocks, making it easier to write more robust and reliable tests.


noob to master © copyleft