Como testar a anotação @Scheduled
1. Introdução
Uma das anotações disponíveis emSpring Framework é@Scheduled. Podemos usar essa anotação paraexecute tasks in a scheduled way.
Neste tutorial, vamos explorar como testar a anotação@Scheduled.
2. Dependências
Primeiro, vamos começar a criar um aplicativo baseado em MavenSpring Boot a partir deSpring Initializer:
org.springframework.boot
spring-boot-starter-parent
2.1.2.RELEASE
Também precisaremos usar alguns iniciadores Spring Boot:
org.springframework.boot
spring-boot-starter
org.springframework.boot
spring-boot-starter-test
test
E vamos adicionar a dependência deJUnit 5 ao nossopom.xml:
org.junit.jupiter
junit-jupiter-api
Podemos encontrar a versão mais recente do Spring Boot emMaven Central.
Além disso, para usarAwaitility em nossos testes, precisamos adicionar sua dependência:
org.awaitility
awaitility
3.1.6
test
3. Amostra@Scheduled simples
Vamos começar criando uma classeCounter simples:
@Component
public class Counter {
private AtomicInteger count = new AtomicInteger(0);
@Scheduled(fixedDelay = 5)
public void scheduled() {
this.count.incrementAndGet();
}
public int getInvocationCount() {
return this.count.get();
}
}
Usaremos o métodoscheduled para aumentar nossocount. Observe que também adicionamos a anotação@Scheduled para executá-la em um período fixo de cinco milissegundos.
Além disso, vamos criar uma classeScheduledConfig para habilitar tarefas agendadas usando a anotação@EnableScheduling:
@Configuration
@EnableScheduling
@ComponentScan("com.example.scheduled")
public class ScheduledConfig {
}
4. Usando teste de integração
Uma das alternativas para testar nossa classe é usarintegration testing. Para fazer isso, precisamos usar a anotação@SpringJUnitConfig para iniciar o contexto do aplicativo e nossos beans no ambiente de teste:
@SpringJUnitConfig(ScheduledConfig.class)
public class ScheduledIntegrationTest {
@Autowired
Counter counter;
@Test
public void givenSleepBy100ms_whenGetInvocationCount_thenIsGreaterThanZero()
throws InterruptedException {
Thread.sleep(100L);
assertThat(counter.getInvocationCount()).isGreaterThan(0);
}
}
Nesse caso, iniciamos nosso beanCounter e esperamos 100 milissegundos para verificar a contagem de invocação.
5. Usando Awaitility
Outra abordagem para testar tarefas agendadas é usarAwaitility. Podemos usar o DSL Awaitility para tornar nosso teste mais declarativo:
@SpringJUnitConfig(ScheduledConfig.class)
public class ScheduledAwaitilityIntegrationTest {
@SpyBean
private Counter counter;
@Test
public void whenWaitOneSecond_thenScheduledIsCalledAtLeastTenTimes() {
await()
.atMost(Duration.ONE_SECOND)
.untilAsserted(() -> verify(counter, atLeast(10)).scheduled());
}
}
Nesse caso, injetamos nosso bean com a anotação@SpyBean para verificar o número de vezes que o métodoscheduled é chamado no período de um segundo.
6. Conclusão
Neste tutorial, mostramos algumas abordagens para testar tarefas agendadas usando o teste de integração e a biblioteca Awaitility.
Precisamos levar em consideração que, embora os testes de integração sejam bons,it’s generally better to focus on the unit testing of the logic inside the scheduled method.
Como de costume, todos os exemplos de código mostrados neste tutorial estão disponíveis emGitHub.