⚡ 3.8 Mocks que Lançam Exceções
Sistemas robustos devem se recuperar de falhas de infraestrutura. O que acontece se o Banco de Dados estiver fora do ar ou o servidor de e-mail (SMTP) falhar durante o processamento de um leilão?
🏗️ Cenário: Resiliência no Encerramento
Imagine que o EncerradorDeLeilao agora deve enviar um e-mail. Se o e-mail falhar, o sistema deve continuar processando os outros leilões (Isolation of Failure).
📄 Código Resiliente (Java 17)
public void encerra() {
var leiloes = dao.correntes();
for (var leilao : leiloes) {
try {
if (comecouSemanaPassada(leilao)) {
leilao.encerra();
dao.atualiza(leilao);
carteiro.envia(leilao); // Nova dependência
total++;
}
} catch (Exception e) {
// Logging e continuidade do fluxo
System.err.println("Falha ao processar leilão: " + leilao.getId());
}
}
}🧪 Simulando Falhas com Mockito 5
Para testar se o sistema realmente continua após um erro, instruímos o Mock a lançar uma exceção.
📄 Testando a Sobrevivência do Loop
@Test
void deveContinuarExecucaoMesmoSeUmComponenteFalhar() {
var leilao1 = new CriadorDeLeilao().para("TV").naData(antiga).constroi();
var leilao2 = new CriadorDeLeilao().para("Geladeira").naData(antiga).constroi();
var daoMock = mock(LeilaoDao.class);
var carteiroMock = mock(Carteiro.class);
when(daoMock.correntes()).thenReturn(List.of(leilao1, leilao2));
// ⚒️ FORÇANDO A FALHA: Lançar exceção no primeiro envio
doThrow(new RuntimeException()).when(carteiroMock).envia(leilao1);
var encerrador = new EncerradorDeLeilao(daoMock, carteiroMock);
encerrador.encerra();
// ✅ Verifica que o segundo leilão foi processado com sucesso
verify(daoMock).atualiza(leilao2);
verify(carteiroMock).envia(leilao2);
assertThat(encerrador.getTotalEncerrados()).isEqualTo(1);
}
---
## 📊 Estratégias de Exceção no Mockito
| Tipo de Invocação | Sintaxe de Elite |
| :--- | :--- |
| **Métodos com Retorno** | `when(...).thenThrow(new RuntimeException())` |
| **Métodos Void** | `doThrow(new Exception()).when(mock).metodo()` |
| **Estilo BDD** | `willThrow(new Exception()).given(mock).metodo()` |
> [!CAUTION] Catch-All 🛡️
>
> Capturar `Exception` de forma genérica é aceitável em loops de processamento em lote (Batch), mas certifique-se de que o erro seja logado adequadamente para análise técnica posterior. 🏁