Перейти к основному содержимому

Как протестировать аннотацию @Scheduled

· 3 мин. чтения

1. Введение

Одна из доступных аннотаций в Spring Framework@Scheduled . Мы можем использовать эту аннотацию для выполнения задач по расписанию .

В этом руководстве мы рассмотрим, как протестировать аннотацию @Scheduled .

2. Зависимости

Во-первых, давайте начнем создавать приложение Spring Boot на основе Maven из Spring Initializer :

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.1</version>
<relativePath/>
</parent>

Нам также понадобится несколько стартеров Spring Boot:

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>

И давайте добавим зависимость для JUnit 5 в наш pom.xml :

<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
</dependency>

Мы можем найти последнюю версию Spring Boot на Maven Central .

Кроме того, чтобы использовать Awaitility в наших тестах, нам нужно добавить его зависимость:

<dependency>
<groupId>org.awaitility</groupId>
<artifactId>awaitility</artifactId>
<version>3.1.6</version>
<scope>test</scope>
</dependency>

3. Простой пример @Scheduled

Начнем с создания простого класса Counter :

@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();
}
}

Мы будем использовать запланированный метод, чтобы увеличить количество . Обратите внимание, что мы также добавили аннотацию @Scheduled для выполнения за фиксированный период в пять миллисекунд.

Кроме того, давайте создадим класс ScheduledConfig для включения запланированных задач с помощью аннотации @EnableScheduling :

@Configuration
@EnableScheduling
@ComponentScan("com.foreach.scheduled")
public class ScheduledConfig {
}

4. Использование интеграционного тестирования

Одной из альтернатив для тестирования нашего класса является использование интеграционного тестирования . Для этого нам нужно использовать аннотацию @SpringJUnitConfig , чтобы запустить контекст приложения и наши bean-компоненты в тестовой среде:

@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);
}
}

В этом случае мы запускаем наш компонент Counter и ждем 100 миллисекунд, чтобы проверить количество вызовов.

5. Использование ожидания

Другой подход к тестированию запланированных задач — использование Awaitility . Мы можем использовать Awaitility DSL, чтобы сделать наш тест более декларативным:

@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());
}
}

В этом случае мы внедряем в наш bean- компонент аннотацию @SpyBean , чтобы проверить, сколько раз запланированный метод вызывается в течение одной секунды.

6. Заключение

В этом руководстве мы показали некоторые подходы к тестированию запланированных задач с использованием интеграционного тестирования и библиотеки Awaitility.

Нужно учитывать, что хотя интеграционные тесты и хороши, в целом лучше сосредоточиться на модульном тестировании логики внутри запланированного метода .

Как обычно, все примеры кода, показанные в этом руководстве, доступны на GitHub .