🎭 Mock Objects: Isolamento e Testabilidade

Até agora, nossos testes de unidade operavam em cenários isolados. Contudo, em sistemas de alta escala, as classes interagem com infraestruturas complexas: Banco de Dados, APIs de Terceiros e Filas de Mensagens.

🏁 O Problema: Acoplamento e APIs Legadas

Analise a classe EncerradorDeLeilao. Ela utiliza o legado java.util.Calendar e possui um acoplamento rígido com o LeilaoDao, tornando o teste de unidade puro impossível sem um banco de dados real.

📄 src/main/java/…/servico/EncerradorDeLeilao.java (Legado)

public class EncerradorDeLeilao {
    private int total = 0;
 
    public void encerra() {
        // ❌ MÁ PRÁTICA: Acoplamento Rígido (Hardcoded Dependency)
        var dao = new LeilaoDao();
        var todosLeiloesCorrentes = dao.correntes();
 
        for (var leilao : todosLeiloesCorrentes) {
            if (comecouSemanaPassada(leilao)) {
                leilao.encerra();
                total++;
                dao.atualiza(leilao);
            }
        }
    }
 
    private boolean comecouSemanaPassada(Leilao leilao) {
        // ❌ MÁ PRÁTICA: Dependência de data do sistema (Não determinístico)
        return ChronoUnit.DAYS.between(leilao.getData(), LocalDate.now()) >= 7;
    }
 
    public int getTotalEncerrados() { return total; }
}

🏗️ Proposta de Elite: Injeção de Dependência

Para tornar o código testável, aplicamos a Inversão de Controle. O EncerradorDeLeilao deve receber suas dependências via construtor, permitindo que injetemos “Dublês” durante o teste.

classDiagram
    class EncerradorDeLeilao {
        -LeilaoDao dao
        +EncerradorDeLeilao(LeilaoDao dao)
        +encerra() void
    }
    class LeilaoDao {
        <<interface>>
        +correntes() List
        +atualiza(Leilao l) void
    }
    EncerradorDeLeilao --> LeilaoDao : Injeta

📄 Código Modernizado (Java 17)

public class EncerradorDeLeilao { private final LeilaoDao dao; private int total = 0;

// ✅ Injeção por Construtor (Design para Testabilidade)
public EncerradorDeLeilao(LeilaoDao dao) {
    this.dao = dao;
}

public void encerra() {
    var todosLeiloesCorrentes = dao.correntes();
    todosLeiloesCorrentes.stream()
        .filter(this::comecouSemanaPassada)
        .forEach(leilao -> {
            leilao.encerra();
            total++;
            dao.atualiza(leilao);
        });
}

private boolean comecouSemanaPassada(Leilao leilao) {
    return ChronoUnit.DAYS.between(leilao.getData(), LocalDate.now()) >= 7;
}

}



> [!IMPORTANT] Mock Objects ao Resgate 🛡️
> 
> Ao desacoplar a criação do DAO, podemos usar o **Mockito 5** para simular o comportamento do banco de dados na memória RAM, garantindo testes que rodam em milissegundos. 🚀

---
[[Desenvolvimento de Sistemas/Desenvolvimento de Sistemas II/capitulo_041|⬅️ Capítulo Anterior]] | [[Desenvolvimento de Sistemas/Desenvolvimento de Sistemas II/capitulo_043|Próximo Capítulo ➡️]]