How to Test the @Scheduled Annotation – 如何测试@Scheduled注释

最后修改: 2019年 2月 12日

中文/混合/英文(键盘快捷键:t)

1. Introduction

1.介绍

One of the available annotations in the Spring Framework is @Scheduled. We can use this annotation to execute tasks in a scheduled way.

Spring框架中的一个可用注解是@Scheduled。我们可以使用这个注解来以预定方式执行任务

In this tutorial, we’ll explore how to test the @Scheduled annotation.

在本教程中,我们将探讨如何测试@Scheduled注释。

2. Dependencies

2.依赖性

First, let’s start creating a Spring Boot Maven-based application from the Spring Initializer:

首先,让我们从Spring Boot开始创建一个基于Maven的应用程序。

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

We’ll also need to use a couple of Spring Boot starters:

我们还需要使用几个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>

And, let’s add the dependency for JUnit 5 to our pom.xml:

而且,让我们把JUnit 5的依赖性添加到我们的pom.xml中。

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

We can find the latest version of Spring Boot on Maven Central.

我们可以在Maven Central上找到Spring Boot的最新版本。

Additionally, to use Awaitility in our tests, we need to add its dependency:

此外,为了在我们的测试中使用Awaitility,我们需要添加其依赖性。

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

3. Simple @Scheduled Sample

3.简单的@Scheduled样本

Let’s start by creating a simple Counter class:

让我们从创建一个简单的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();
    }
}

We’ll use the scheduled method to increase our count. Note that we’ve also added the @Scheduled annotation to execute it in a fixed period of five milliseconds.

我们将使用scheduled方法来增加我们的count。请注意,我们还添加了@Scheduled注解,以便在5毫秒的固定时间内执行它。

Also, let’s create a ScheduledConfig class to enable scheduled tasks using the @EnableScheduling annotation:

另外,让我们创建一个ScheduledConfig类,使用@EnableScheduling注解启用计划任务。

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

4. Using Integration Testing

4.使用集成测试

One of the alternatives to test our class is using integration testing. To do that, we need to use the @SpringJUnitConfig annotation to start the application context and our beans in the testing environment:

测试我们的类的替代方法之一是使用集成测试。要做到这一点,我们需要使用@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);
    }
}

In this case, we start our Counter bean and wait for 100 milliseconds to check the invocation count.

在这种情况下,我们启动我们的Counter Bean并等待100毫秒以检查调用次数。

5. Using Awaitility

5.使用 “等待”

Another approach to testing scheduled tasks is using Awaitility. We can use the Awaitility DSL to make our test more declarative:

测试计划任务的另一种方法是使用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());
    }
}

In this case, we inject our bean with the @SpyBean annotation to check the number of times that the scheduled method is called in the period of one second.

在这种情况下,我们用@SpyBean注解注入我们的bean,以检查scheduled方法在一秒钟内被调用的次数。

6. Conclusion

6.结论

In this tutorial, we showed some approaches to test scheduled tasks using integration testing and the Awaitility library.

在本教程中,我们展示了一些使用集成测试和Awaitility库来测试预定任务的方法。

We need to take into account that, although integration tests are good, it’s generally better to focus on the unit testing of the logic inside the scheduled method.

我们需要考虑到,虽然集成测试很好,但一般来说,最好是把重点放在预定方法内部逻辑的单元测试上

As usual, all the code samples shown in this tutorial are available over on GitHub.

像往常一样,本教程中显示的所有代码样本都可以在GitHub上获得。