🧪 1.19 Testando Exceções sob Pressão

Arquiteturas resilientes devem prever o fracasso. O tratamento de cenários excepcionais é tão vital quanto o fluxo de sucesso. No nosso leilão, o que acontece se tentarmos avaliar um pregão sem lances?

🏗️ Implementando a Proteção de Negócio

Validamos o estado antes do processamento. Se não houver lances, interrompemos o fluxo com uma exceção clara:

public void avalia(Leilao leilao) {
    if (leilao.getLances().isEmpty()) {
        throw new IllegalArgumentException("Não é possível avaliar um leilão sem lances!");
    }
    // ... lógica de avaliação ...
}

🛠️ Estratégias Modernas de Teste (JUnit 5 + AssertJ)

O JUnit 5 aposentou o atributo (expected = ...) do JUnit 4 em favor de uma abordagem funcional muito mais poderosa e flexível.

🏁 Abordagem Jupiter: assertThrows

A forma nativa do JUnit 5 utiliza lambdas para capturar a exceção e permitir validações posteriores:

@Test
void naoDeveAvaliarLeilaoSemLances() {
    var leilao = new CriadorDeLeilao().para("Playstation 5").constroi();
 
    var excecao = assertThrows(IllegalArgumentException.class, () -> {
        leiloeiro.avalia(leilao);
    });
 
    // Validando a mensagem da exceção
    assertEquals("Não é possível avaliar um leilão sem lances!", excecao.getMessage());
}

🏆 Abordagem de Elite: AssertJ assertThatThrownBy

Para máxima legibilidade, o AssertJ oferece uma sintaxe fluída que descreve exatamente o que se espera:

@Test
void deveLancarExcecaoParaLeilaoSemLances() {
    var leilao = new CriadorDeLeilao().para("Playstation 5").constroi();
 
    assertThatThrownBy(() -> leiloeiro.avalia(leilao))
            .isInstanceOf(IllegalArgumentException.class)
            .hasMessageContaining("sem lances");
}

📊 Comparativo Técnico

RecursoJUnit 4 (Legacy)JUnit 5 / AssertJ (Moderno)
SintaxeAtributo @Test(expected)Funcional (Lambdas)
PrecisãoFraca (qualquer linha pode falhar)Alta (apenas o bloco lambda é vigiado)
Validação da MensagemDifícil (exige try-catch manual)Nativa e fluída

Use o Padrão Moderno 🛡️

Evite o uso de try-catch em testes. As ferramentas modernas (assertThrows ou assertThatThrownBy) garantem que o teste falhe corretamente se a exceção NÃO for lançada, eliminando a necessidade de Assert.fail(). 🏁


⬅️ Capítulo Anterior | Próximo Capítulo ➡️