0
votes

I am trying to test the Spring Batch steps. I have 2 scenarios to test 1. Step with tasklet (step scoped) 2. Step with ItemReader/ItemWriter (step scope)

My test class is annotated as follows

@RunWith(SpringJUnit4ClassRunner.class)
@TestExecutionListeners({DependencyInjectionTestExecutionListener.class, StepScopeTestExecutionListener.class})
@ContextConfiguration(loader = SpringApplicationContextLoader.class, classes = ItemReturnsApplication.class)

This is how my test class looks like

@Bean
    JobLauncherTestUtils jobLauncherTestUtils(){
        return new JobLauncherTestUtils();
    }

    @Autowired
    private JobLauncherTestUtils jobLauncherTestUtils;

@Test
    public void testLaunchJob() throws Exception{
        JobExecution jobExecution = jobLauncherTestUtils.launchJob(
                new JobParametersBuilder().addString("chunkSize", "3").addString("current_date","2016-11-25").toJobParameters()
        );
        commonAssertions(jobLauncherTestUtils.launchJob());
        assertEquals(BatchStatus.COMPLETED, jobExecution.getStatus());
    }

When I run the test case, the process fails because the the job parameters are not getting passed into my job.

I am looking for the right way of testing the Step Scoped steps in spring batch.

Thanks, Opensource Explorer

1

1 Answers

1
votes

Your current code attempts to launch and test a job and not a step. According to the spring batch documentation on how to test individual steps, a simple example of how to test a tasklet and inject context into the tasklet is more in line with the following code:

@ContextConfiguration
@TestExecutionListeners( { DependencyInjectionTestExecutionListener.class,
    StepScopeTestExecutionListener.class })
@RunWith(SpringJUnit4ClassRunner.class)
public class StepScopeTestExecutionListenerIntegrationTests {

    // This component is defined step-scoped, so it cannot be injected unless
    // a step is active...
    @Autowired
    private YourTaskletClass yourTaskletClass;

    public StepExecution getStepExection() {
        StepExecution execution = MetaDataInstanceFactory.createStepExecution();
        execution.getExecutionContext().putString("input.data", "foo,bar,spam");
        return execution;
    }

    @Test
    public void testYourTaskletClass() {
        // The tasklet is initialized and some configuration is already set by the MetaDatAInstanceFactory           
        assertNotNull(yourTaskletClass.doSomething());
    }

}

The @RunWith(SpringJUnit4ClassRunner.class) annotation is only possible with a spring boot version of 1.4 and higher. For more information see this blog.

To launch an individual step try adjusting your code to:

@RunWith(SpringJUnit4ClassRunner.class)
@TestExecutionListeners({DependencyInjectionTestExecutionListener.class, StepScopeTestExecutionListener.class})
@ContextConfiguration(loader = SpringApplicationContextLoader.class, classes = ItemReturnsApplication.class)    
public class StepIntegrationTest {

    @Autowired
    private JobLauncherTestUtils jobLauncherTestUtils;

    @Test
    public void testLaunchJob() throws Exception{
       JobExecution jobExecution = jobLauncherTestUtils.launchStep("nameOfYourStep");

    } 
}