Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Batch JUnit test for multiple jobs

I am having two jobs configured in one context file

<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>

When i am doing unit testing for the JobA using JobLauncherTestUtils and testing the job launch it is throwing an exception saying

No unique bean of type [org.springframework.batch.core.Job;] is defined: expected single matching bean but found 2: [JobA, JobB]

i tried using @Qualifier for autowire still the same thing. Where am i doing wrong here

edited

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

exception was

No unique bean of type [org.springframework.batch.core.Job;] is defined: expected single matching bean but found 2: [JobA, JobB]`
like image 968
pavan Avatar asked Dec 11 '15 06:12

pavan


People also ask

Can a Spring Batch have multiple jobs?

Multiple jobs can be run simultaneously. There are two main types of Spring Batch Parallel Processing: Single Process, Multi-threaded, or Multi-process.

What is Stepscope in Spring Batch?

The step scope means that Spring will create the bean only when the step asks for it and that values will be resolved then (this is the lazy instantiation pattern; the bean isn't created during the Spring application context's bootstrapping).

How do I check my Spring Batch job status?

You can get the status of the last job (so, the one running if there is one running) with http://localhost:8080/sprin-batch-admin-sample/batch/jobs/job1.json (replacing with job1 your actual job name and server). The parameter lastJobExecutionStatus should be STARTING , STARTED or STOPPING if it's still running.

How do you access job parameters in Spring Batch?

JobParameters can be used for identification or even as reference data during the job run. They have reserved names, so to access them we can use Spring Expression Language. For example to access a property 'abc' on job parameters: we can access it using the syntax #{jobParameters[abc]} .


1 Answers

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)

like image 119
Ilya Dyoshin Avatar answered Sep 19 '22 09:09

Ilya Dyoshin