JUnit 5 и Mockito assertThrows() вызывают исключение NullPointerException вместо исходного

Я хочу протестировать метод, который должен вызывать исключение типа 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>

Дикое предположение, что в вашем тесте нет @ExtendWith(MockitoExtension.class) или используется неправильный @Test (тот, что из JUnit4 вместо JUnit5). Но поскольку вы разместили только частичный фрагмент вместо полного теста, это невозможно узнать.

M. Deinum 20.02.2023 11:34

@M.Deinum Добавлено больше деталей к вопросу.

Michi-2142 20.02.2023 11:43

Я ожидаю, что трассировка стека даст вам четкое представление о том, почему вы получаете NPE.

k314159 20.02.2023 12:00

Я бы начал с обновления Mockito. 4.0.0 немного устарела, я бы по крайней мере попробовал 4.11 или даже переключился на релизы 5.x. Это еще не полный тестовый пример, так как я ожидаю некоторого дополнительного импорта.

M. Deinum 20.02.2023 12:07

Ваш код должен перехватывать NPE и повторно выдавать его как ваш тип исключения. Либо так, либо если вы получите NPE в своей службе, пусть он выдаст ваш тип исключения.

Dale 20.02.2023 12:11

@M.Deinum M.Deinum Обновление до 4.11 дает мне подробный журнал, спасибо!

Michi-2142 20.02.2023 13:00

Почему @Spy? Вы не следите за звонками и не перехватываете звонки

knittl 20.02.2023 13:53
Как сделать движок для футбольного матча? (простой вариант)
Как сделать движок для футбольного матча? (простой вариант)
Футбол. Для многих людей, живущих на земле, эта игра - больше, чем просто спорт. И эти люди всегда мечтают стать футболистом или менеджером. Но, к...
Знайте свои исключения!
Знайте свои исключения!
В Java исключение - это событие, возникающее во время выполнения программы, которое нарушает нормальный ход выполнения инструкций программы. Когда...
Лучшая компания по разработке спортивных приложений
Лучшая компания по разработке спортивных приложений
Ищете лучшую компанию по разработке спортивных приложений? Этот список, несомненно, облегчит вашу работу!
Blibli Automation Journey - Как захватить сетевой трафик с помощью утилиты HAR в Selenium 4
Blibli Automation Journey - Как захватить сетевой трафик с помощью утилиты HAR в Selenium 4
Если вы являетесь веб-разработчиком или тестировщиком, вы можете быть знакомы с Selenium, популярным инструментом для автоматизации работы...
Фото ️🔁 Radek Jedynak 🔃 on ️🔁 Unsplash 🔃
Фото ️🔁 Radek Jedynak 🔃 on ️🔁 Unsplash 🔃
Что такое Java 8 Streams API? Java 8 Stream API
Деревья поиска (Алгоритм4 Заметки к учебнику)
Деревья поиска (Алгоритм4 Заметки к учебнику)
(1) Двоичные деревья поиска: среднее lgN, наихудшее N для вставки и поиска.
0
7
52
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Проблема в аннотации @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).

M. Deinum 20.02.2023 13:31

Другие вопросы по теме