Для чего используется аннотация @SpringBootTest?

Ответ

@SpringBootTest — основная аннотация Spring Boot для интеграционного тестирования, которая загружает полный контекст приложения.

Что она делает:

  1. Автоматически находит и загружает конфигурацию из класса, помеченного @SpringBootApplication.
  2. Создает ApplicationContext, идентичный контексту реального приложения.
  3. При необходимости запускает встроенный веб-сервер (Tomcat, Jetty, Netty).

Основные параметры:

  • webEnvironment: определяет тип веб-окружения.
    • WebEnvironment.NONE — без веб-сервера (тесты для сервисного слоя).
    • WebEnvironment.RANDOM_PORT — сервер запускается на случайном порту.
    • WebEnvironment.DEFINED_PORT — сервер использует порт из server.port (обычно 8080).

Пример теста с REST-запросом:

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class UserControllerIntegrationTest {
    @Autowired
    private TestRestTemplate restTemplate;

    @Test
    void getUser_ReturnsUser() {
        // Действие: Отправка HTTP-запроса
        ResponseEntity<UserDto> response = restTemplate
                .getForEntity("/api/users/1", UserDto.class);

        // Проверка:
        assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
        assertThat(response.getBody().getId()).isEqualTo(1);
    }
}

Когда использовать: Для сквозного (end-to-end) тестирования, когда нужен доступ ко всем бинам (сервисы, репозитории, контроллеры). Для тестирования отдельных слоев предпочтительнее использовать @WebMvcTest (MVC) или @DataJpaTest (JPA).

Ответ 18+ 🔞

А, ну вот, смотри, подъехали к главному аттракциону — @SpringBootTest. Это, блядь, как взять всё твоё приложение, запихнуть в тестовый полигон и сказать: «Ну-ка, покажи, как ты тут будешь работать, когда тебя реально запустят, сука?».

Что она творит, эта аннотация:

  1. Автоматически ищет твой главный класс с @SpringBootApplication и грузит оттуда всю хуйню — конфиги, бины, всё на свете.
  2. Создаёт ApplicationContext — точь-в-точь как в реальной жизни, только в тестовом режиме. Не какая-то там подделка, а полный пакет.
  3. Если надо, может ещё и встроенный веб-сервер поднять (Tomcat, Jetty), чтобы ты мог по-настоящему, с чувством, долей и ебальником, слать HTTP-запросы.

Основные рычаги и кнопки:

  • webEnvironment: тут ты решаешь, насколько глубоко хочешь погрузиться.
    • WebEnvironment.NONE — веб-сервер не нужен, тестируем просто сервисы, без всей этой HTTP-мишуры. Экономим время, не грузим лишнее.
    • WebEnvironment.RANDOM_PORT — вот это уже серьёзно. Сервер запускается на случайном порту, чтобы не было конфликтов, и ты можешь долбить в него запросы, как в боевой. Охуенно для интеграционных тестов контроллеров.
    • WebEnvironment.DEFINED_PORT — сервер встанет на порт из твоего application.properties (обычно 8080). Осторожно, если порт занят — тест пиздец.

Пример, чтобы стало совсем понятно, как этим пользоваться:

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class UserControllerIntegrationTest {
    @Autowired
    private TestRestTemplate restTemplate; // Этот чувак поможет нам долбануть запрос

    @Test
    void getUser_ReturnsUser() {
        // Действие: Отправляем HTTP-запрос, будто мы Postman, только в коде
        ResponseEntity<UserDto> response = restTemplate
                .getForEntity("/api/users/1", UserDto.class);

        // Проверка: А не обманули ли нас?
        assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
        assertThat(response.getBody().getId()).isEqualTo(1);
    }
}

Когда это всё городить: Когда тебе нужно проверить ВСЁ ЦЕЛИКОМ — от контроллера через сервис и репозиторий до базы. Это сквозное тестирование, end-to-end, ёпта. Но если тебе нужно потестить только контроллеры (без поднятия всего контекста) — юзай @WebMvcTest. Если только JPA-слой — @DataJpaTest. А @SpringBootTest — это когда терпения ебать ноль и хочется увидеть картину маслом, со всеми деталями, даже если это будет дольше.