知識庫 / Spring RSS 訂閱

如何測試@Scheduled註解

Spring,Testing
HongKong
6
01:28 PM · Dec 06 ,2025

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 庫測試計劃任務的一些方法。

我們需要考慮到,雖然集成測試是有用的,但通常更應該關注計劃方法內部邏輯的單元測試

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.