Mockito – Better error messages on NPE with globally configured SmartNull
Instead of just a line when NullPointerException occurred:
java.lang.NullPointerException at PlantWaterer.generateNPE(PlantWaterer.java:24) at DefaultValuesTest.shouldReturnNicerErrorMessageOnNPE(DefaultValuesTest.java:64)
we have also got descriptive information what method was not stubbed:
org.mockito.exceptions.verification.SmartNullPointerException: You have a NullPointerException here: ?> at PlantWaterer.generateNPE(PlantWaterer.java: 24) because this method call was ?not? stubbed correctly: ?> at PlantWaterer.generateNPE(PlantWaterer.java: 24) wateringScheduler.returnNull(); at PlantWaterer.generateNPE(PlantWaterer.java: 24) at DefaultValuesTest.shouldReturnNicerErrorMessageOnNPE(DefaultValuesTest.java:64)
A particular mock can be instructed to return SmartNull instead of the null value:
PlantWaterer plantWatererMock = mock(PlantWaterer.class, Mockito.RETURNS_SMART_NULLS);
or
@Mock(answer = Answers.RETURNS_SMART_NULLS) private PlantWaterer plantWatererMock;
SmartNull will be probably the default bahavior in Mockito 2.0, but for the backward compatibility in 1.9.x it is necessary to tell every mock explicitly to use it. The need to write another piece of boilerplate code causes that almost nobody uses SmartNull despite it is a very useful feature. And there the second almost unknown element of Mockito enters the game – global configuration. Generally there is no need to configure Mockito. It just works. But for some rare cases the framework’s authors left a gate which allows to override the default configuration of a few core behaviors, including the default answer policy for unstubbed methods.
To make it work it is necessary to create org.mockito.configuration.MockitoConfiguration class (necessarily in that package) which implements IMockitoConfiguration interface. Usually it is comfortable to extend DefaultMockitoConfiguration class and only override desired behavior(s).
package org.mockito.configuration; import org.mockito.internal.stubbing.defaultanswers.ReturnsSmartNulls; import org.mockito.stubbing.Answer; public class MockitoConfiguration extends DefaultMockitoConfiguration { public Answer<Object> getDefaultAnswer() { return new ReturnsSmartNulls(); } }
After that preparation we should get SmartNullPointerException with the verbose output instead of the pure NullPointerException for every mock in our module.
@Test(expectedExceptions = SmartNullPointerException.class) public void shouldReturnNicerErrorMessageOnNPE() { //given //Mockito.RETURNS_SMART_NULLS not needed anymore WateringScheduler wateringSchedulerMock = mock(WateringScheduler.class); WaterSource waterSourceMock = mock(WaterSource.class); PlantWaterer plantWatererMock = new PlantWaterer(waterSourceMock, wateringSchedulerMock); //when plantWatererMock.generateNPE(); //then //SmartNullPointerException exception expected }
This post is the first part of the series Beyond the Mockito refcard.
Reference: Beyond the Mockito refcard – part 1 – Better error messages on NPE with globally configured SmartNull from our JCG partner Marcin Zajaczkowski at the Solid Soft blog.