Вместо строки, когда произошло исключение NullPointerException:
1
2
3
|
java.lang.NullPointerException at PlantWaterer.generateNPE(PlantWaterer.java:24) at DefaultValuesTest.shouldReturnNicerErrorMessageOnNPE(DefaultValuesTest.java:64) |
мы также получили описательную информацию о том, какой метод не был заглушен:
1
2
3
4
5
6
7
8
9
|
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) |
Конкретный макет может быть проинструктирован возвращать SmartNull вместо нулевого значения:
1
2
|
PlantWaterer plantWatererMock = mock(PlantWaterer. class , Mockito.RETURNS_SMART_NULLS); |
или же
1
2
|
@Mock (answer = Answers.RETURNS_SMART_NULLS) private PlantWaterer plantWatererMock; |
SmartNull, вероятно, будет поведением по умолчанию в Mockito 2.0, но для обратной совместимости в 1.9.x необходимо явно указывать каждому макету использовать его. Необходимость написания еще одного стандартного кода приводит к тому, что почти никто не использует SmartNull, несмотря на то, что это очень полезная функция. И там в игру вступает второй почти неизвестный элемент Mockito — глобальная конфигурация. Как правило, нет необходимости настраивать Mockito. Это просто работает. Но в некоторых редких случаях авторы фреймворка оставили шлюз, который позволяет переопределить конфигурацию по умолчанию для нескольких основных вариантов поведения, включая политику ответов по умолчанию для методов без меток.
Чтобы это работало, необходимо создать класс org.mockito.configuration.MockitoConfiguration ( обязательно в этом пакете ), который реализует интерфейс IMockitoConfiguration. Обычно удобно расширять класс DefaultMockitoConfiguration и переопределять только желаемое поведение.
01
02
03
04
05
06
07
08
09
10
11
|
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(); } } |
После этой подготовки мы должны получить SmartNullPointerException с подробным выводом вместо чистого NullPointerException для каждого макета в нашем модуле.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
|
@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 } |
Этот пост является первой частью серии Beyond the Mockito refcard .
Ссылка: Помимо рефкарт Mockito — часть 1 — Лучшие сообщения об ошибках в NPE с глобально настроенным SmartNull от нашего партнера по JCG Марцина Заячковского в блоге Solid Soft .