9

I've implemented a simple job with 2 tasklets. I want to test the second tasklet by passing parameters.

I've read the Spring batch documentation and below my test:

@RunWith(SpringRunner.class)
@SpringBootTest
@ActiveProfiles({"test"})
@TestExecutionListeners( { DependencyInjectionTestExecutionListener.class,
        StepScopeTestExecutionListener.class })
public class EtudeBatchApplicationTests {
    @Autowired
    private JobLauncherTestUtils jobLauncherTestUtils;

    public StepExecution getStepExecution() {
        StepExecution execution = MetaDataInstanceFactory.createStepExecution();
        execution.getJobExecution().getExecutionContext().putString("myValue", "foo,bar,spam");
        return execution;
    }

    @Test
    public void contextLoads() {

        JobExecution jobExecution = jobLauncherTestUtils.launchStep("insertIncludedSiretsStep");
    }

}

My problem is in my tasklet, the myValue is always null.

Below, the code of the tasklet:

@Component
@StepScope
@Slf4j
public class InsertIncludedSiretsTask implements Tasklet {
    @Override
    public RepeatStatus execute(StepContribution stepContribution, ChunkContext chunkContext) throws Exception {
        Object myValue = chunkContext.getStepContext().getStepExecution().getJobExecution().getExecutionContext().get("myValue");

        log.info("INSERTINCLUDEDSIRETSTASK runnning");
        Thread.sleep(3000);
        return RepeatStatus.FINISHED;

    }
}
ChriX
  • 951
  • 4
  • 9
  • 22

2 Answers2

9

You can mock the ChunkContext following this example :

http://www.javased.com/index.php?source_dir=spring-insight-plugins/collection-plugins/spring-batch/src/test/java/com/springsource/insight/plugin/springbatch/TaskletCollectionAspectTest.java

Here is my code :

public ChunkContext createChunkContext() {
    StepExecution stepExecution=Mockito.mock(StepExecution.class);
    StepContext stepContext=Mockito.mock(StepContext.class);
    ChunkContext chunkContext=Mockito.mock(ChunkContext.class);
    JobExecution jobExecution= createJobExecution();

    Mockito.when(chunkContext.getStepContext()).thenReturn(stepContext);
    Mockito.when(stepContext.getStepExecution()).thenReturn(stepExecution);
    Mockito.when(stepExecution.getJobExecution()).thenReturn(jobExecution);

    return chunkContext;
}
public JobExecution createJobExecution() {
    JobExecution execution = MetaDataInstanceFactory.createJobExecution();
    execution.getExecutionContext().putString("myValue", "foo,bar,spam");
    return execution;
}

@Test
public void testSendEmail() throws Exception {
    StepContribution contribution= Mockito.mock(StepContribution.class);
    ChunkContext chunkContext= createChunkContext();


    sendReportTasklet.execute(contribution, chunkContext );
    }
Melkior
  • 91
  • 1
  • 5
3

Based on Melkior answer which helped me a lot I simplify the test:

public class MyTaskletTest {

    private static final String MY_JOB_PARAM = "my.job.param";

    @Mock
    private StepContribution stepContribution;

    @Mock
    private StepExecution stepExecution;

    @Mock
    private StepContext stepContext;

    @Mock
    private ChunkContext chunkContext;

    private MyTasklet tasklet;

    @Before
    public void setupTest() {
        when(chunkContext.getStepContext()).thenReturn(stepContext);
        when(stepContext.getStepExecution()).thenReturn(stepExecution);
    }

    @Override
    public void init() {
        tasklet = new MyTasklet();
    }

    @Test
    public void should_test_my_tasklet() throws Exception {
        when(stepExecution.getJobParameters()).thenReturn(defaultJobParameters("myParam"));
        tasklet.execute(stepContribution, chunkContext);
    }

    private JobParameters defaultJobParameters(String myParam) {
        JobParametersBuilder paramsBuilder = new JobParametersBuilder();
        paramsBuilder.addString(MY_JOB_PARAM, myParam);
        return paramsBuilder.toJobParameters();
    }

}

Dharman
  • 30,962
  • 25
  • 85
  • 135
Guilherme Bernardi
  • 490
  • 1
  • 6
  • 18