JobLauncherTestUtils 는 자체적으로 Job Bean 을 주입받아야 한다. 컨텍스트에 테스트용 Job Bean 이 없거나, 여러 Job Bean 이 존재해서 Spring 이 어떤 Job 을 사용해야 할지 모르는 상태에서 launchJob() 을 호출 하면 The Job must not be null 또는 NoUniqueBeanDefinitionException 이 발생할 수 있다.
@SpringBatchTest 를 붙이면 테스트 전용 컨텍스트에 JobLauncherTestUtils 빈이 자동으로 생성된다. Batch 4 에서는 launchJob() 호출 시에 유일한 Job 이 있으면 알아서 그 Job 을 사용했지만, Batch 5 에서는 job 필드가 자동으로 Autowired 되지 않아서(null 상태) 직접 setjob() 으로 지정해주는 것이 필수다. JobLauncherTestUtils 는 job 필드가 null 이면 실행이 불가하다.
테스트에서 사용하는 Job(expiredPassesJob) 이 애플리케이션 컨텍스트에 등록되어 있지 않아서 JobLauncherTestUtils 가 Job 을 못 찾는다면 테스트용 Job 을 명시적으로 지정해주는 것이 안전하다.
@TestConfiguration
public class JobConfigTests {
@Bean
public Job expiredPassesJob(JobRepository jobRepository, Step expirePassesStep) {
return new JobBuilder("expiredPassesJob", jobRepository)
.start(expirePassesStep)
.build();
}
}
Job Bean 이 여러개라 못 찾고 있다면 @Qualifier 로 이름 지정해주거나 JobLauncherTestUtils 에 setJob() 으로 Job 을 직접 연결해주면 된다.
Import 로 테스트 클래스가 테스트용 Job Config 를 명시적으로 가져오도록 해준다. main Application.java 에서 정의된 Job 과는 분리된 테스트 전용 Job 을 사용하게 되고 원본 Job 과 충돌을 방지할 수 있다.
테스트를 진행할 Job 빈을 JobLauncherTestUtils 에 setJob() 으로 연결한다.
@Slf4j
@SpringBatchTest
@SpringBootTest
@Import(JobConfigTests.class)
@ActiveProfiles("test")
class ExpirePassesJobConfigTest {
@Autowired
private JobLauncherTestUtils jobLauncherTestUtils;
@BeforeEach
void setUp(@Qualifier("expiredPassesJob") Job expiredPassesJob) {
jobLauncherTestUtils.setJob(expiredPassesJob);
}
}
테스트 전용 Job 을 등록해준 다음에
JobLauncherTestUtils 에 @Autowired 해준 후
@BeforeEach 에서 setJob()으로 연결해주면 된다.