Skip to content

Implementar testes de integração críticos #23

@wallanpsantos

Description

@wallanpsantos

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 requestperformanceMelhoria de performance

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions