[SPRING] 여러 작업에 대한 Spring Batch JUnit 테스트
SPRING여러 작업에 대한 Spring Batch JUnit 테스트
하나의 컨텍스트 파일에 두 개의 작업이 구성되어 있습니다.
<batch:job id="JobA" restartable="true">
<batch:step id="abc">
<batch:tasklet >
<batch:chunk reader="reader" writer="writer" processor="processor" />
</batch:tasklet>
</batch:step>
</batch:job>
<batch:job id="JobB" restartable="true">
<batch:step id="abc">
<batch:tasklet >
<batch:chunk reader="reader" writer="writer" processor="processor" />
</batch:tasklet>
</batch:step>
</batch:job>
JobLauncherTestUtils를 사용하여 JobA에 대한 단위 테스트를 수행하고 작업 시작을 테스트 할 때 예외가 발생했습니다.
No unique bean of type [org.springframework.batch.core.Job;] is defined: expected single matching bean but found 2: [JobA, JobB]
나는 autowire에 @Qualifier를 사용해 보았는데 여전히 같은 것을 사용했다. 내가 여기서 잘못하고있는 곳
편집 한
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:META-INF/spring/batch-test-context.xml" })
public class TestJob {
@Autowired
private JobExplorer jobExplorer;
@Autowired
@Qualifier("JobA")
private Job JobA;
@Autowired
private JobLauncherTestUtils jobLauncherTestUtils;
@Test
public void testJob() throws Exception {
JobParameters jobParameters = getNextJobParameters(getJobParameters());
assertEquals(BatchStatus.COMPLETED, jobLauncherTestUtils.getJobLauncher().run(JobA, jobParameters));
}
private JobParameters getJobParameters() {
JobParametersBuilder jobParameters = new JobParametersBuilder();
jobParameters.addString("param", "123");
return jobParameters.toJobParameters();
}
private JobParameters getNextJobParameters(JobParameters jobParameters) {
String jobIdentifier = jobLauncherTestUtils.getJob().getName();
List<JobInstance> lastInstances = jobExplorer.getJobInstances(jobIdentifier, 0, 1);
JobParametersIncrementer incrementer = jobLauncherTestUtils.getJob().getJobParametersIncrementer();
if (lastInstances.isEmpty()) {
return incrementer.getNext(jobParameters);
} else {
List<JobExecution> lastExecutions = jobExplorer.getJobExecutions(lastInstances.get(0));
return incrementer.getNext(lastExecutions.get(0).getJobParameters());
}
}
}
예외는
No unique bean of type [org.springframework.batch.core.Job;] is defined: expected single matching bean but found 2: [JobA, JobB]`
해결법
-
==============================
1.어쩌면 늦었 어.
어쩌면 늦었 어.
하지만 스스로 해결책을 찾았습니다 : JobLauncherTestUtils의 수동 구성 :
@Inject @Qualifier(value = "Job1") private Job job; @Inject private JobLauncher jobLauncher; @Inject private JobRepository jobRepository; private JobLauncherTestUtils jobLauncherTestUtils; private void initailizeJobLauncherTestUtils() { this.jobLauncherTestUtils = new JobLauncherTestUtils(); this.jobLauncherTestUtils.setJobLauncher(jobLauncher); this.jobLauncherTestUtils.setJobRepository(jobRepository); this.jobLauncherTestUtils.setJob(job); } @Before public void setUp() throws Exception { this.initailizeJobLauncherTestUtils(); }
JobLauncherTestUtils를 적용해야하는 Job을 제어 할 수 있습니다. (기본적으로 컨텍스트에서 단일 작업 구성이 필요함)
-
==============================
2.빈 환경 설정 파일에 선언 된 두 개의 비슷한 빈을 가지고있다. 위의 문제를 해결하기 위해 @Qualifier ( "JobA")와 @Qualifier ( "JobB")가 필요하다.
빈 환경 설정 파일에 선언 된 두 개의 비슷한 빈을 가지고있다. 위의 문제를 해결하기 위해 @Qualifier ( "JobA")와 @Qualifier ( "JobB")가 필요하다.
-
==============================
3.JobLauncherTestUtils.setJob (Job job)에 대한 setter에 @Autowired 주석이 있기 때문에 Bean이 생성 된 후에 MergedBeanDefinitionPostProcessor를 사용하여 속성을 설정해야했습니다.
JobLauncherTestUtils.setJob (Job job)에 대한 setter에 @Autowired 주석이 있기 때문에 Bean이 생성 된 후에 MergedBeanDefinitionPostProcessor를 사용하여 속성을 설정해야했습니다.
@Configuration public class TestBatchConfiguration implements MergedBeanDefinitionPostProcessor { @Autowired @Qualifier("JobA") private Job job; @Bean(name="jtestl") public JobLauncherTestUtils jobLauncherTestUtils() { JobLauncherTestUtils jobLauncherTestUtils = new JobLauncherTestUtils(); jobLauncherTestUtils.setJob(job); return jobLauncherTestUtils; } /** * https://stackoverflow.com/questions/22416140/autowire-setter-override-with-java-config * This is needed to inject the correct job into JobLauncherTestUtils */ @Override public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) { if(beanName.equals("jtestl")) { beanDefinition.getPropertyValues().add("job", getMyBeanFirstAImpl()); } } private Object getMyBeanFirstAImpl() { return job; } @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { return bean; } }
-
==============================
4.개별적으로 JobLauncherTestUtils를 작성하여 해결했습니다 (groovy).
개별적으로 JobLauncherTestUtils를 작성하여 해결했습니다 (groovy).
@TestConfiguration class BatchJobTestConfiguration { @Autowired @Qualifier('job1') private Job job1 @Autowired @Qualifier('job2') private Job job2 @Autowired JobRepository jobRepository; @Bean JobLauncher jobLauncher() throws Exception { SimpleJobLauncher jobLauncher = new SimpleJobLauncher(); jobLauncher.setJobRepository(jobRepository); jobLauncher.setTaskExecutor(new SyncTaskExecutor()); jobLauncher.afterPropertiesSet(); return jobLauncher; } @Bean(name = 'jobLauncherTestUtilsJob1') JobLauncherTestUtils jobLauncherTestUtilsSyncEndUserJob() { new JobLauncherNoAutowireTestUtil( job: job1, jobLauncher: jobLauncher() ) } @Bean(name = 'jobLauncherTestUtilsJob2') JobLauncherTestUtils jobLauncherTestUtilsenewCaseJob() { new JobLauncherNoAutowireTestUtil( job: job2, jobLauncher: jobLauncher() ) }
그런 다음 테스트에 추가하십시오.
@ContextConfiguration(classes = [BatchJobTestConfiguration]) ... @Autowired @Qualifier('jobLauncherTestUtilsJob1') private JobLauncherTestUtils jobLauncherTestUtils ... when: def jobExecution = jobLauncherTestUtils.launchJob()
-
==============================
5.원래의 문제에 대한 대답은 아니지만, 아래 코드를 사용하여 동일한 클래스의 테스트 케이스를 순차적으로 실행하는 동안 JobLauncherTestUtils를 재사용하지 않았습니다.
원래의 문제에 대한 대답은 아니지만, 아래 코드를 사용하여 동일한 클래스의 테스트 케이스를 순차적으로 실행하는 동안 JobLauncherTestUtils를 재사용하지 않았습니다.
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
이는 Junit이 각 실행 후에 컨텍스트를 정리하고 다시 구성하도록 지시합니다.
from https://stackoverflow.com/questions/34217101/spring-batch-junit-test-for-multiple-jobs by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] Tomcat에서 JPA, Hibernate 및 Spring을 사용하여 클래스 로더 누출을 피하는 방법 (0) | 2019.04.12 |
---|---|
[SPRING] 자바의 미래 - Spring 인증은 AuditorAware에서 null입니다. (0) | 2019.04.12 |
[SPRING] Spring MVC Controller의 클래스 속성으로서 Session scope bean (0) | 2019.04.12 |
[SPRING] json 파일에서 spring-boot 특성로드 (0) | 2019.04.12 |
[SPRING] 사용자 정의 속성 편집기가 Spring MVC의 요청 매개 변수에 대해 작동하지 않습니까? (0) | 2019.04.12 |