1. 소개

Spring Framework 에서 사용 가능한 어노테이션 중 하나 @Scheduled 입니다. 이 어노테이션을 사용 하여 예약된 방식으로 작업을 실행할 수 있습니다 .

이 사용방법(예제)에서는 @Scheduled 어노테이션을 테스트하는 방법을 살펴봅니다.

2. 의존성

먼저 Spring Initializer 에서 Spring Boot  Maven 기반 애플리케이션을  생성해 보겠습니다 .

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.7.2</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>

Maven Central 에서 최신 버전의 Spring Boot를 찾을 수 있습니다 .

또한 테스트에서 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();
    }
}

예약 된 방법을 사용하여 카운트 를 늘릴 것 입니다. 5밀리초의 고정된 기간에 실행하기 위해 @Scheduled 어노테이션 도 추가했습니다 .

또한 @EnableScheduling 어노테이션 을 사용하여 예약된 작업을 활성화하는 ScheduledConfig 클래스를 생성해 보겠습니다.

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

4. 통합 테스트 사용

클래스를 테스트하는 대안 중 하나는 통합 테스트 를 사용하는 것 입니다. 이를 위해서는  @SpringJUnitConfig 어노테이션을 사용하여 테스트 환경에서 애플리케이션 컨텍스트와 빈을 시작해야 합니다.

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

이 경우 예약 된 메서드가 1초 동안 호출되는 횟수를 확인하기 위해 @SpyBean 어노테이션을 빈에 주입합니다  .

6. 결론

이 사용방법(예제)에서는 통합 테스트 및 Awaitility 라이브러리를 사용하여 예약된 작업을 테스트하는 몇 가지 접근 방식을 보여주었습니다.

통합 테스트가 좋지만 일반적으로 예약된 메서드 내 논리의 단위 테스트에 집중하는 것이 더 낫다 는 점을 고려해야 합니다  .

늘 그렇듯이 이 예제에 표시된 모든 코드 샘플은 GitHub 에서 사용할 수 있습니다 .

Junit footer banner