Spring Boot 통합 시 @Schedule 사용 안 함시험
Spring Boot Integration Test에서 예약 자동 시작을 비활성화하려면 어떻게 해야 합니까?
감사해요.
외부 구성 요소가 자동으로 스케줄링을 활성화할 수 있습니다(HystrixStream 참조).자동 구성 및 메트릭 내보내기Spring Framework에서 자동 구성).그래서 만약 당신이 시도하고 사용한다면.@ConditionalOnProperty
또는@Profile
에서.@Configuration
를 지정하는 @EnableScheduling
그러면 외부 구성 요소로 인해 예약이 활성화됩니다.
하나의 솔루션
하나 가져요@Configuration
▁▁via▁▁enables스래클을 통해 스케줄링을 가능하게 하는 @EnableScheduling
하지만 예약된 작업을 별도의 클래스에 두고, 각 클래스에서 사용합니다.@ConditionalOnProperty
@Scheduled 작업이 포함된 클래스를 활성화/비활성화합니다.
그럴 필요 없어요@Scheduled
그리고.@EnableScheduling
클래스에 요소가할 수 . 같은클 있나거에래, 외부구는활문하있것로제므이을가화성어,@ConditionalOnProperty
무시됩니다.
예:
@Configuration
@EnableScheduling
public class MyApplicationSchedulingConfiguration {
}
그리고 다른 수업에서.
@Named
@ConditionalOnProperty(value = "scheduling.enabled", havingValue = "true", matchIfMissing = false)
public class MyApplicationScheduledTasks {
@Scheduled(fixedRate = 60 * 60 * 1000)
public void runSomeTaskHourly() {
doStuff();
}
}
이 솔루션의 문제는 예약된 모든 작업이 다음과 같은 클래스에 있어야 한다는 것입니다.@ConditionalOnProperty
됩니다.해당 주석을 놓치면 작업이 실행됩니다.
다른 솔루션
확장기를 합니다.ThreadPoolTaskScheduler
그리고 그것을 무시합니다.TaskScheduler
이러한 할 수 .이러한 방법으로 작업을 실행할지 여부를 확인할 수 있습니다.
그런 다음 @EnableScheduling을 사용하는 @Configuration 클래스에서 사용자 지정 스레드 풀 작업 스케줄러를 반환하는 @Bean(작업 스케줄러)도 만듭니다.
예:
public class ConditionalThreadPoolTaskScheduler extends ThreadPoolTaskScheduler {
@Inject
private Environment environment;
// Override the TaskScheduler methods
@Override
public ScheduledFuture<?> schedule(Runnable task, Trigger trigger) {
if (!canRun()) {
return null;
}
return super.schedule(task, trigger);
}
@Override
public ScheduledFuture<?> schedule(Runnable task, Date startTime) {
if (!canRun()) {
return null;
}
return super.schedule(task, startTime);
}
@Override
public ScheduledFuture<?> scheduleAtFixedRate(Runnable task, Date startTime, long period) {
if (!canRun()) {
return null;
}
return super.scheduleAtFixedRate(task, startTime, period);
}
@Override
public ScheduledFuture<?> scheduleAtFixedRate(Runnable task, long period) {
if (!canRun()) {
return null;
}
return super.scheduleAtFixedRate(task, period);
}
@Override
public ScheduledFuture<?> scheduleWithFixedDelay(Runnable task, Date startTime, long delay) {
if (!canRun()) {
return null;
}
return super.scheduleWithFixedDelay(task, startTime, delay);
}
@Override
public ScheduledFuture<?> scheduleWithFixedDelay(Runnable task, long delay) {
if (!canRun()) {
return null;
}
return super.scheduleWithFixedDelay(task, delay);
}
private boolean canRun() {
if (environment == null) {
return false;
}
if (!Boolean.valueOf(environment.getProperty("scheduling.enabled"))) {
return false;
}
return true;
}
}
사용자 지정 스케줄러를 사용하여 taskSchedulerbean 작업을 만들고 스케줄링을 활성화하는 구성 클래스
@Configuration
@EnableScheduling
public class MyApplicationSchedulingConfiguration {
@Bean
public TaskScheduler taskScheduler() {
return new ConditionalThreadPoolTaskScheduler();
}
}
위의 잠재적인 문제는 내부 Spring 클래스에 종속성을 생성했기 때문에 향후 변경 사항이 있을 경우 호환성을 수정해야 한다는 것입니다.
저도 같은 문제가 있었습니다.맛을 시험해 보았습니다.@ConditionalOnProperty
내 Scheduling Bean의 속성이지만 테스트에서 여전히 Scheduling이 활성화되었습니다.
내가 찾은 유일한 좋은 해결 방법은 테스트 클래스의 예약 속성을 덮어써서 작업을 실행할 수 있는 실제 기회가 없도록 하는 것이었습니다.
속성을 사용하여 5분마다 실제 작업이 실행되는 경우my.cron=0 0/5 * * * *
public class MyJob {
@Scheduled(cron = "${my.cron}")
public void execute() {
// do something
}
}
그런 다음 테스트 클래스에서 다음과 같이 구성할 수 있습니다.
@RunWith(SpringRunner.class)
@SpringBootTest(properties = {"my.cron=0 0 0 29 2 ?"}) // Configured as 29 Feb ;-)
public class MyApplicationTests {
@Test
public void contextLoads() {
}
}
따라서 작업이 활성화되더라도 4년에 한 번 발생하는 2월 29일 0시에만 실행됩니다.따라서 실행할 가능성은 매우 희박합니다.
당신의 요구 사항에 맞게 더 화려한 cron 설정을 생각해 낼 수 있습니다.
Spring Boot 2.0.3에서 알아낸 쉬운 해결책:
예약된 메서드를 별도의 빈에 추출
@Service
public class SchedulerService {
@Autowired
private SomeTaskService someTaskService;
@Scheduled(fixedRate = 60 * 60 * 1000)
public void runSomeTaskHourly() {
someTaskService.runTask();
}
}
당신의 시험 수업에서 스케줄러 빈을 조롱합니다.
@RunWith(SpringRunner.class)
@SpringBootTest
public class SomeTaskServiceIT {
@Autowired
private SomeTaskService someTaskService;
@MockBean
private SchedulerService schedulerService;
}
한 가지 방법은 스프링 프로필을 사용하는 것입니다.
테스트 클래스:
@SpringBootTest(classes = Application.class)
@ActiveProfiles("integration-test")
public class SpringBootTestBase {
...
}
스케줄러 클래스 또는 메서드:
@Configuration
@Profile("!integration-test") //to disable all from this configuration
public class SchedulerConfiguration {
@Scheduled(cron = "${some.cron}")
@Profile("!integration-test") //to disable a specific scheduler
public void scheduler1() {
// do something
}
@Scheduled(cron = "${some.cron}")
public void scheduler2() {
// do something
}
...
}
실제 Spring Boot Application 클래스가 다음과 같은 경우:
@SpringBootApplication
@EnableScheduling
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
다음과 같은 통합 테스트를 위해 @EnableScheduling 없이 다른 응용 프로그램 클래스를 만들어야 합니다.
@SpringBootApplication
public class MyTestApplication {
public static void main(String[] args) {
SpringApplication.run(MyTestApplication.class, args);
}
}
그런 다음 통합 테스트에서 MyTestApplication 클래스를 사용합니다.
RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = MyTestApplication.class)
public class MyIntegrationTest {
...
}
저는 더 좋은 방법을 찾지 못했기 때문에 그렇게 하고 있습니다.
별도의 구성 클래스를 사용하여 이 문제를 해결한 다음 테스트 컨텍스트에서 이 클래스를 덮어씁니다.따라서 애플리케이션에 주석을 다는 대신 별도의 구성 클래스에만 주석을 달았습니다.
일반 컨텍스트:
@Configuration
@EnableScheduling
public class SpringConfiguration {}
테스트 컨텍스트:
@Configuration
public class SpringConfiguration {}
위의 몇 가지 답변 통합:
- 테스트를 위해 별도의 구성 클래스를 만듭니다("TestConfiguration.class"라고도 함).
다른 콩(스케줄러 등)에 대한 Mockito 주석을 활성화합니다.
- Read this: 2)
@ConditionalOnClass @ConditionalOnMissingBean @ConditionalOnBean @ConditionalOnJava @ConditionalOnJndi @ConditionalOnMissingClass @ConditionalOnExpression @ConditionalOnNotWebApplication @ConditionalOnWebApplication @ConditionalOnProperty @ConditionalOnResource @ConditionalOnSingleCandidate
또한 항상 확인:
- 외부 장치/서비스에 따라 "application.yml" 자체 생성 속성
- 메인 클래스 브레이킹빈 초기화 시퀀스에 대한 자동 구성 주석
- "applicationContext.xml", "beans.xml" 또는 클래스 경로 로더
다음을 읽어 보십시오.
- SpringBoot 자동 구성
- Spring Boot 자동 구성 작동 방식
다음과 같은 테스트를 위해 필요하지 않은 콩에 조롱 주석을 사용해 보십시오.
@MockBean private StoresRatingAvgScheduler scheduler; @Before public void init() { MockitoAnnotations.initMocks(this); }
언급URL : https://stackoverflow.com/questions/40684903/disable-schedule-on-spring-boot-integrationtest
'IT' 카테고리의 다른 글
벡터 또는 열에서 두 번째(세 번째...) 가장 높은/낮은 값을 찾는 가장 빠른 방법 (0) | 2023.07.07 |
---|---|
python 명령줄을 종료하는 중 (0) | 2023.07.07 |
'WITH' 절을 사용하여 SQL Server 쿼리에 이상한 오류가 발생함 (0) | 2023.07.07 |
쿼리에서 고유하게 사용해야 합니까? (0) | 2023.07.07 |
vuej의 서버에서 데이터를 가져오는 방법은 무엇입니까? (0) | 2023.07.07 |