1. 簡介
Spring 框架中可用的註解之一是 @Scheduled。我們可以使用此註解以定時的方式執行任務。
在本次教程中,我們將探討如何測試 @Scheduled 註解。
2. 依賴項
首先,讓我們從 Spring Initializer 創建一個基於 Maven 的 Spring Boot 應用程序:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<relativePath/>
</parent>我們還需要使用一些 Spring Boot Starter:
<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>讓我們為我們的 pom.xml 添加 JUnit 5 的依賴項:
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
</dependency>我們可以從 Maven Central 找到 Spring Boot 的最新版本。
為了在我們的測試中使用 Awaitility,我們需要添加它的依賴項:
<dependency>
<groupId>org.awaitility</groupId>
<artifactId>awaitility</artifactId>
<version>3.1.6</version>
<scope>test</scope>
</dependency>3. 簡單的 @Scheduled 示例
讓我們從創建一個簡單的 計數器 類開始:
@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 方法來增加我們的 count。請注意,我們還添加了 @Scheduled 註解,以便在固定時間間隔(五毫秒)內執行該任務。
另外,讓我們創建一個 ScheduledConfig 類,以使用 @EnableScheduling 註解啓用定時任務:
@Configuration
@EnableScheduling
@ComponentScan("com.baeldung.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 Bean,並等待 100 毫秒來檢查調用次數。
5. 使用 Awaitility
使用 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 註解,來檢查在 1 秒內 scheduled 方法被調用的次數。
6. 結論
在本教程中,我們展示了使用集成測試和 Awaitility 庫測試計劃任務的一些方法。
我們需要考慮到,雖然集成測試是有用的,但通常更應該關注計劃方法內部邏輯的單元測試。