Я хочу протестировать метод, который должен вызывать исключение типа MyCustomException
. Это пример моего класса MyService
.
public class MyService {
public void invoke(InvocationContext ctx) throws MyCustomException{
if (ctx == null) {
throw new MyCustomException("Parameter ctx must not be null.");
}
}
}
Я хотел бы проверить, выдает ли метод MyCustomException
, если я передаю нулевое значение с помощью assertThrows()
.
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mockito;
import org.mockito.Spy;
import org.mockito.junit.jupiter.MockitoExtension;
@ExtendWith(MockitoExtension.class)
public class AxwApplicationTest {
@Spy
@InjectMocks
MyService myServiceToTest;
@Test
public void invoke_ShouldThrow_MyCustomException() {
assertThrows(MyCustomException.class, () -> {
myServiceToTest.invoke(null);
});
}
}
Каким-то образом возникает исключение, но оно заканчивается как NullPointerException
, и я не знаю, как его решить. assertThrows
выдает следующую ошибку:
java.lang.AssertionError: unexpected exception type thrown; expected:<com.myproject.MyCustomException> but was:<java.lang.NullPointerException>
Зависимости Maven:
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.9.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>4.0.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>4.0.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<version>4.0.0</version>
<scope>test</scope>
</dependency>
@M.Deinum Добавлено больше деталей к вопросу.
Я ожидаю, что трассировка стека даст вам четкое представление о том, почему вы получаете NPE.
Я бы начал с обновления Mockito. 4.0.0 немного устарела, я бы по крайней мере попробовал 4.11 или даже переключился на релизы 5.x. Это еще не полный тестовый пример, так как я ожидаю некоторого дополнительного импорта.
Ваш код должен перехватывать NPE и повторно выдавать его как ваш тип исключения. Либо так, либо если вы получите NPE в своей службе, пусть он выдаст ваш тип исключения.
@M.Deinum M.Deinum Обновление до 4.11 дает мне подробный журнал, спасибо!
Почему @Spy
? Вы не следите за звонками и не перехватываете звонки
проблема в аннотации @InjectMocks
и @Spy
. Использование их вместе не имеет смысла (как обсуждалось в этом посте stackoverflow). Создание класса вручную решает проблему NullPointerException
, и тест проходит успешно
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mockito;
import org.mockito.Spy;
import org.mockito.junit.jupiter.MockitoExtension;
import static
org.junit.jupiter.api.Assertions.assertThrows;
@ExtendWith(MockitoExtension.class)
public class MyServiceTest {
MyService myServiceToTest;
@Test
public void invoke_ShouldThrow_MyCustomException() {
MyService myServiceToTest = new MyService();
assertThrows(MyCustomException.class, () -> {
myServiceToTest.invoke(null);
});
}
}
Вам даже не нужен @ExtendWith
с этим (это фактически замедлит скорость вашего теста, поскольку он будет сканировать класс на наличие аннотаций mockito).
Дикое предположение, что в вашем тесте нет
@ExtendWith(MockitoExtension.class)
или используется неправильный@Test
(тот, что из JUnit4 вместо JUnit5). Но поскольку вы разместили только частичный фрагмент вместо полного теста, это невозможно узнать.