-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Labels
enhancementNew feature or requestNew feature or requestperformanceMelhoria de performanceMelhoria de performance
Description
Título: Add comprehensive integration tests covering critical scenarios
Labels: high, testing, integration
Prioridade: ALTA
Próximos Passos Sugeridos (do Feedback):
Incluir testes integrados cobrindo:
- Duplicidade em retries
- Conflitos de versão
- Falhas entre persistência e publicação
- Reconstrução de saldo
Solução Proposta:
@SpringBootTest
@Testcontainers
class WalletIntegrationTest {
@Container
static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:15")
.withDatabaseName("wallet_test")
.withUsername("test")
.withPassword("test");
@Test
void shouldHandleRetryDuplication() {
String idempotencyKey = "test-key-001";
// Primeira chamada
WalletTransaction result1 = depositUseCase.execute(userId, amount, idempotencyKey);
// Segunda chamada (retry) - deve retornar mesmo resultado
WalletTransaction result2 = depositUseCase.execute(userId, amount, idempotencyKey);
assertThat(result1.getId()).isEqualTo(result2.getId());
// Verificar que só houve uma transação no banco
List<WalletTransaction> transactions = findAllTransactions(userId);
assertThat(transactions).hasSize(1);
}
@Test
void shouldHandleOptimisticLockingConflicts() throws InterruptedException {
CountDownLatch latch = new CountDownLatch(2);
List<Exception> exceptions = new CopyOnWriteArrayList<>();
// Simular dois threads tentando atualizar a mesma wallet
Runnable deposit = () -> {
try {
depositUseCase.execute(userId, Money.of(BigDecimal.TEN, "BRL"));
} catch (Exception e) {
exceptions.add(e);
} finally {
latch.countDown();
}
};
new Thread(deposit).start();
new Thread(deposit).start();
latch.await(10, TimeUnit.SECONDS);
// Deve haver exatamente 2 depósitos (retry automático funcionou)
Money balance = getBalanceUseCase.execute(userId);
assertThat(balance.getAmount()).isEqualTo(new BigDecimal("20.00"));
}
@Test
void shouldRollbackOnOutboxFailure() {
// Simular falha no outbox publisher
when(outboxEventPublisher.publishOutboxEvent(any(), any()))
.thenThrow(new RuntimeException("Kafka down"));
assertThatThrownBy(() ->
depositUseCase.execute(userId, Money.of(BigDecimal.TEN, "BRL")))
.isInstanceOf(RuntimeException.class);
// Verificar que nem wallet nem transação foram persistidas
Money balance = getBalanceUseCase.execute(userId);
assertThat(balance.getAmount()).isEqualTo(BigDecimal.ZERO);
List<WalletTransaction> transactions = findAllTransactions(userId);
assertThat(transactions).isEmpty();
}
@Test
void shouldRecalculateBalanceCorrectly() {
// Criar múltiplas transações
depositUseCase.execute(userId, Money.of(new BigDecimal("100"), "BRL"));
withdrawUseCase.execute(userId, Money.of(new BigDecimal("30"), "BRL"));
depositUseCase.execute(userId, Money.of(new BigDecimal("50"), "BRL"));
// Recalcular saldo histórico
LocalDate yesterday = LocalDate.now().minusDays(1);
Money historicalBalance = getHistoricalBalance.execute(userId, yesterday);
Money currentBalance = getBalanceUseCase.execute(userId);
assertThat(currentBalance.getAmount()).isEqualTo(new BigDecimal("120.00"));
}
}Tarefas:
- Configurar Testcontainers com PostgreSQL
- Testes de idempotência/retry
- Testes de optimistic locking concorrente
- Testes de rollback transacional
- Testes de performance com alto volume
- Testes de recuperação de falhas
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or requestperformanceMelhoria de performanceMelhoria de performance