Ответ
Для интеграционного тестирования в Java-экосистеме применяется комбинация инструментов:
| Инструмент | Назначение |
|---|---|
| JUnit 5 / TestNG | Базовый движок для написания тестов. |
Spring Boot Test (@SpringBootTest) |
Поднятие тестового контекста Spring. |
| REST Assured | Удобное тестирование REST API. |
| Testcontainers | Запуск реальных зависимостей (БД, Kafka) в Docker-контейнерах. |
| WireMock | Мокирование внешних HTTP-сервисов. |
| DBUnit / Liquibase | Управление тестовыми данными в БД. |
Пример интеграционного теста для Spring Boot REST-контроллера:
@SpringBootTest
@AutoConfigureMockMvc
class UserControllerIntegrationTest {
@Autowired
private MockMvc mockMvc;
@Test
void getUser_ShouldReturnUser_WhenUserExists() throws Exception {
mockMvc.perform(get("/api/users/{id}", 1L)
.accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$.id").value(1));
}
}
Такой стек позволяет тестировать приложение в условиях, близких к production.
Ответ 18+ 🔞
Слушай, а вот эти ваши интеграционные тесты в Java — это ж целая ёбаная опера, как в Большом театре, только вместо балерин — контейнеры, а вместо дирижёра — твой убитый в хлам CI-сервер.
Смотри, какие инструменты народ в кучу сваливает, чтобы проверить, не развалится ли его творение нахуй при первом же чихе:
| Инструмент | Зачем он, этот ёбушки-воробушки? |
|---|---|
| JUnit 5 / TestNG | Ну, основа основ, движок. Без него ты как без штанов — тесты писать не на чем. |
Spring Boot Test (@SpringBootTest) |
Чтобы поднять весь этот весёлый цирк — контекст Spring, блядь, со всеми бинами, словно ёлка на Новый год. |
| REST Assured | Чтоб не изгаляться с HttpURLConnection, а по-человечьи API щупать. Удобно, чёрт возьми. |
| Testcontainers | Вот это, блядь, песня! Запускает реальную PostgreSQL, Kafka, Redis в докере — так что твои тесты уже почти в проде, только без клиентов. |
| WireMock | Когда нужно накостылять заглушку на внешний сервис, который вечно лежит или требует миллион долларов за вызов. |
| DBUnit / Liquibase | Чтобы данные в БД не как попало, а по красоте — подготовил, проверил, почистил. |
А теперь смотри, как это выглядит в коде, когда ты всё это скрещиваешь. Блок кода не трогаю, как договаривались, но вокруг него можно похахать:
@SpringBootTest // Поднимаем весь контекст, блядь, будто бы не в тесте, а в жизни.
@AutoConfigureMockMvc // Чтоб MockMvc сам приехал, как такси по вызову.
class UserControllerIntegrationTest {
@Autowired
private MockMvc mockMvc; // Вот он, красавец, билетик в твой REST.
@Test
void getUser_ShouldReturnUser_WhenUserExists() throws Exception {
mockMvc.perform(get("/api/users/{id}", 1L) // Дёргаем эндпоинт, как будто с фронта пришло.
.accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk()) // Ждём, что не кинет 500-ку с криком "чё тебе надо?"
.andExpect(jsonPath("$.id").value(1)); // И что в ответе id будет единица, а не левая нога.
}
}
И знаешь, в чём прикол-то? Если собрать этот паззл правильно, то твоё приложение будет тестироваться в условиях, максимально близких к боевым. То есть не просто "ой, метод вызвался", а "бля, а с реальной БД-то оно работает? А если внешний сервис заглушить? А если в контейнере?". Это ж почти продакшн, только без пользователей, которые вечно жалуются, что кнопка не того цвета.
Вот так и живём: поднимаем пол-опенсорса, чтобы убедиться, что наш UserController не обосрётся при простом GET-запросе. Красота, ёпта!