Spring Batch JUnit test for multiple jobs

只愿长相守 提交于 2019-11-29 07:21:24

Maybe late,

but I found for myself working solution: manual configuration of 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();
}

with this you can control for which Job should JobLauncherTestUtils be applied. (by default it expects single Job configuration in context)

You have two similar beans declared in bean configuration file. To fix above problem, you need @Qualifier("JobA") and @Qualifier("JobB") to tell Spring about which bean should auto wired to which job.

Because there is an @Autowired annotation on the setter for JobLauncherTestUtils.setJob(Job job) I had to use a MergedBeanDefinitionPostProcessor to set the property after the bean was created:

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

I solved it by creating JobLauncherTestUtils for each job separately (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()
    )
}

Then add this into your test:

@ContextConfiguration(classes = [BatchJobTestConfiguration])
...
@Autowired
@Qualifier('jobLauncherTestUtilsJob1')
private JobLauncherTestUtils jobLauncherTestUtils
...
when:
def jobExecution = jobLauncherTestUtils.launchJob()

Not answer to original problem, but using below code we have avoided reuse of JobLauncherTestUtils during sequential run of test cases in same class.

@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)

This indicates Junit to clean up and re construct context after each run.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!