Ответ
Да, я сталкивался с тестированием систем, построенных с использованием паттерна Saga (или Orchestration-based Saga) для управления распределенными транзакциями в микросервисной архитектуре. Основной фокус был на проверке согласованности данных и отказоустойчивости.
Ключевые аспекты тестирования:
- Счастливый путь (Happy Path): Проверка, что при успешном выполнении всех шагов (сервисов) саги система приходит в корректное целевое состояние.
- Компенсирующие транзакции (Compensation): Тестирование сценариев, когда один из шагов завершается ошибкой. Убеждался, что для всех уже выполненных шагов запускаются корректные компенсирующие действия (компенсации) и система откатывается в согласованное состояние.
- Идемпотентность: Проверка, что повторный вызов шага или компенсации (например, из-за таймаута сети) не приводит к побочным эффектам или нарушению консистенции данных.
- Восстановление после сбоев: Тестирование поведения саги при временной недоступности сервисов (retry logic) и корректности обработки таймаутов.
Пример интеграционного теста (концептуальный):
// Пример для Spring Boot / JUnit 5, тестирующий сценарий отката
@Test
void orderSaga_ShouldCompensate_WhenPaymentServiceFails() {
// 1. Запускаем сагу создания заказа
OrderSaga saga = startOrderSaga(testOrderData);
// 2. Мокаем сервис оплаты, чтобы он симулировал сбой
when(paymentServiceClient.process(any())).thenThrow(new ServiceUnavailableException());
// 3. Выполняем сагу
saga.execute();
// 4. Проверяем результаты компенсации:
// - Заказ должен иметь статус "CANCELLED"
assertThat(orderRepository.findById(saga.getOrderId()))
.isPresent().get().hasFieldOrPropertyWithValue("status", OrderStatus.CANCELLED);
// - Должен был быть вызван компенсирующий вызов в сервис инвентаря
verify(inventoryServiceClient).compensateReservation(saga.getOrderId());
// - Пользователь должен быть уведомлен
verify(notificationServiceClient).sendCancellationNotification(any());
}
Для таких тестов критически важно иметь хорошо изолированное тестовое окружение с заглушками (stubs/mocks) для всех вовлеченных сервисов.