Integration Testing with Spring – Mocking II

Gil Zilberfeld explains how to using mocking in Spring integration tests
Standard
In this series we're taking at Spring and its features supporting testing in general, and specifically integration tests.
Dependency injectionConfigurationsNested configurationsOrganizing configurations
Primary beansAvoiding problemsProfilesMocking I - Lifecycle
Mocking II - ResetMocking III - MockBeanData I - @SQLData II - JDBC

Data III - JPA
Controllers IControllers IIConsumer tests

Last time we talked about the mocking injection issue with Spring, and discussed the option of using Spring’s “prototype” injection. We figured out, this solution is not for everyone.

What can we do with a regular, Spring singleton mock?

Resetting mocks

Mockito has a nifty little method called reset. As you can guess, it resets everything about a mock (or list of mocks). It resets all expectations, and in our case, method call tracking.

So, we can rewrite our Spring integration tests (using the original singleton configuration) like this:

The mockPublisher is @Autowired again, a singleton like in the original integration test class, and is injected once. Before each integration test, we reset the mock to start from scratch (we can also use @After for the same effect), and presto! Both integration tests pass.

In order for this method to work, we need to add a @Before method, and don’t forget call reset. It’s a bit manual, and if people forget it, they tests quickly fail and remind them.

However…

There’s a minor (read: huge) problem with this method. Since there’s only a singleton instance in our Spring application, reset resets the mock object for everyone who’s got a reference of it. Not just for our tests, but also for other consumers.

Suppose our configuration looked like this:

The doThrow behavior setting, that everyone should have enjoyed, is reset also whenever Mockito.reset is called. So even if our tests don’t use it, it may fail other tests as well that planned to use it.

So here’s a tip for you. When creating mocks in configuration classes, don’t don’t do anything but create them. Additional behaviors should be set only in the tests.

Now that we got this off our chests, there’s one more option we’ll explore next time: the humble MockBean.

Leave a Reply

Your email address will not be published. Required fields are marked *