programing

통합 테스트를 위해 스프링 부트 @EnableAsync 사용 안 함

lastmoon 2023. 7. 6. 22:31
반응형

통합 테스트를 위해 스프링 부트 @EnableAsync 사용 안 함

사용하지 않도록 설정합니다.@EnableAsync통합 테스트를 실행할 때 사용합니다.

주석이 달린 구성 파일을 덮어쓰려고 했습니다.@EnableAsync테스트 패키지에 같은 이름의 클래스가 포함되어 있지만 작동하지 않습니다.

이 항목:통합 테스트 중에 Spring의 @Async를 비활성화할 수 있습니까?

본 적이 있습니다.

당신은...테스트 구성을 만들거나 SyncTask를 사용하여 작업 실행자를 재정의합니다.실행자

하지만 어떻게 해야 할지 모르겠어요

조언이 있습니까?감사해요.

당신이 링크한 주제는 좋은 해결책을 제공합니다.

작성 방법SyncTaskExecutor테스트의 경우 스프링 컨텍스트에 대한 테스트 구성 클래스가 있는지 확인합니다.그것에 대해서는 스프링 문서를 참조하십시오. https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-testing.html

이 구성 클래스에서 새 빈을 추가합니다.

@Bean
@Primary
public TaskExecutor taskExecutor() {
    return new SyncTaskExecutor();
}

그거면 충분해요!

라이브 구성에서 이 빈을 만들지 않도록 주의하십시오!

테스트를 실행할 때 고유한 프로필 이름이 사용되는 경우(예: "테스트"), 테스트를 실행할 때 비동기를 비활성화하는 가장 쉬운 방법은

import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.scheduling.annotation.EnableAsync;


@Profile("!test")
@Configuration
@EnableAsync
public class AsyncConfiguration {

}

저의 경우 다음 사항을 추가해야 했습니다.src/test/resources/application.yml테스트가 "test"라는 이름의 프로필에서 실행되는지 확인합니다.

spring:
  profiles:
    active: test

테스트 폴더에 다음 클래스를 생성하여 기본 태스크 실행자를 덮어쓸 수 있습니다.

@TestConfiguration
public class TestAsyncConfig {
    // create this bean if you have a custom executor you want to overwrite
    @Bean(name = "xxxxxxx") 
    public Executor xxxxxxx() {
        return new SyncTaskExecutor();
    }

    // this will overwrite the default executor
    @Bean
    public Executor taskExecutor() { 
        return new SyncTaskExecutor();
    }
}

그런 다음 통합 테스트의 주석에 다음을 추가합니다.

@ContextConfiguration(classes = TestAsyncConfig.class)

우리는 결국 소품을 사용하게 되었습니다.yourcompany.someExecutor.async기본적으로 사용되는true(그래서 그것은 다음에 나타나지 않습니다.application.yml) 그리고 테스트에서 우리는 그것을 설정했습니다.false사용합니다. 그 소품을 기반으로 우리는 초기화를 합니다.SyncTaskExecutor또는 일부 비동기 버전(예:ThreadPoolTaskExecutor).

이 기능을 사용하면 여러 개의 소품을 사용할 수 있으므로 소품별로 특정 실행자를 쉽게 비활성화할 수 있습니다.이 경우 상황에 따라 여러 비동기 실행자가 있습니다.

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@TestPropertySource(properties = {
        "yourcompany.someExecutor.async=false",
})
public class SomeIntegrationTest {
  // ... tests requiring async disabled
}
@Configuration
public class SomeConfig {
    // ...
    @Value("${yourcompany.someExecutor.async:true}")
    private boolean asyncEnabled;

    @Bean("someExecutor") // specific executor
    public Executor algoExecutor() {
        if (!asyncEnabled) {
            return new SyncTaskExecutor();
        }
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(THREAD_COUNT);
        executor.setMaxPoolSize(THREAD_COUNT);
        executor.setQueueCapacity(QUEUE_CAPACITY);
        executor.setThreadNamePrefix("Some-");
        executor.initialize();
        return executor;
    }
}

당신은 또한 당신의 클래스에서 두 개의 메소드를 만들 수 있습니다. 하나는 다음과 같습니다.@Async그 안에 주석이 있고, 이 주석 없이 테스트해야 하는 모든 논리를 가지고 있고 첫 번째 방법이 두 번째 방법을 호출하도록 하는 두 번째 방법이 있습니다.그런 다음 테스트에서 두 번째 방법을 호출합니다.package-private가시거리

예:

@Async
public void methodAsync() {
    this.method();
}

void method() {
   // Your business logic here!
}

언급URL : https://stackoverflow.com/questions/47411267/spring-boot-disable-enableasync-for-integration-tests

반응형