Ответ
Тестирование микросервисов сложнее из-за распределенности, сетевого взаимодействия и независимого жизненного цикла сервисов.
Стратегия тестирования (Тестировочная пирамида для микросервисов):
[ Контрактные тесты ]
/
[ Интеграционные тесты ] [ Тестирование событий ]
/
[ Компонентные тесты ]
|
[ Модульные тесты ]
1. Модульные тесты (Unit): Проверка логики внутри одного сервиса в изоляции (JUnit, pytest). 2. Компонентные тесты: Тестирование сервиса в изоляции с подменой внешних зависимостей (баз данных, других сервисов) на заглушки (Testcontainers для БД, WireMock для HTTP, встроенный Kafka для брокера). 3. Интеграционные тесты: Проверка взаимодействия между несколькими сервисами через реальные протоколы (HTTP, gRPC). 4. Контрактные тесты (Pact): Гарантируют, что сервисы-потребители и сервисы-поставщики соблюдают согласованный API-контракт, что позволяет им развиваться независимо. 5. Тестирование событийной коммуникации: Валидация корректности публикации и потребления сообщений (Kafka, RabbitMQ).
Пример компонентного теста с Testcontainers и WireMock:
@Testcontainers
public class OrderServiceComponentTest {
@Container
static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:15");
@Test
void shouldProcessOrderWhenPaymentServiceIsAvailable() {
// 1. Заглушка для внешнего Payment Service
WireMockServer wireMock = new WireMockServer();
wireMock.stubFor(post(urlEqualTo("/pay")).willReturn(okJson("{"status":"SUCCESS"}")));
wireMock.start();
// 2. Настройка тестового приложения с подмененным URL платежного сервиса
OrderService service = new OrderService(postgres.getJdbcUrl(), wireMock.baseUrl());
// 3. Выполнение и проверка
Order result = service.placeOrder(new OrderRequest("item-1"));
assertThat(result.getStatus()).isEqualTo(OrderStatus.CONFIRMED);
wireMock.stop();
}
}
Дополнительные аспекты: Тестирование устойчивости (resilience) — circuit breakers, retries, fallbacks; использование распределенной трассировки (Jaeger, Zipkin) для отладки сквозных сценариев.