⏱️ 3.10 Isolando o Tempo com java.time.Clock
Sistemas reais dependem do tempo, mas o tempo é o maior inimigo da estabilidade dos testes. Se o seu código usa LocalDate.now(), o teste pode passar hoje e falhar amanhã. Na Engenharia de Elite, abstraímos o relógio.
🏗️ O Problema do Relógio Estático
Códigos que chamam o sistema operacional diretamente são “Caixas Pretas”. Para torná-los determinísticos, devemos injetar um Relógio (Clock).
📄 Implementação Premium (Java 17)
Em vez de criar interfaces customizadas, o Java 8+ já fornece o java.time.Clock, que é perfeitamente integrado com a API de datas.
public class GeradorDePagamento {
private final Clock clock; // ✅ Abstração nativa do Java
public GeradorDePagamento(Clock clock, ...) {
this.clock = clock;
}
public void gera() {
// ... lógica ...
var hoje = LocalDate.now(clock); // ✅ Agora o 'hoje' é controlável!
var pagamento = new Pagamento(valor, proximoDiaUtil(hoje));
}
}🧪 O Teste Determinístico (Freezing Time)
No Mockito, podemos injetar um relógio “congelado” em qualquer data específica para validar regras como feriados ou fins de semana.
@Test
void deveEmpurrarParaSegundaSeForSabado() {
// 🥶 Congelando o tempo no Sábado, 07/Abril/2012
var sabadoExato = Instant.parse("2012-04-07T10:00:00Z");
var clockMock = Clock.fixed(sabadoExato, ZoneId.of("UTC"));
var gerador = new GeradorDePagamento(clockMock, ...);
gerador.gera();
// Captura e validação...
assertThat(pagamento.getData()).isEqualTo("2012-04-09"); // Segunda-feira
}Injeção de Relógio 🛡️
Ao adotar o
Clock, você ganha o superpoder de viajar no tempo em seus testes. Isso elimina 100% dos testes flutuantes (flaky tests) causados por viradas de dia, ano bissexto ou fusos horários. 🚀
Dica de Ouro ⚡
No Spring Boot, você pode declarar um
@BeandeClock.systemDefaultZone()e injetá-lo em seus serviços. Nos testes, basta substituir porClock.fixed(). 🏁