0

I'm implementing a Spring Batch application. There are a couple of Tasklets with StepExecutionListener. I want to know how to unit test them. For example below sample Tasklet:

public class MyTasklet implements Tasklet, StepExecutionListener {
      
  private List<File> inputFiles;

  @Override
  public void beforeStep(StepExecution stepExecution) {
    log.info("MyTasklet started.");
    ExecutionContext executionContext = stepExecution
        .getJobExecution()
        .getExecutionContext();
    inputFiles = (List<File>) executionContext.get("inputs");
  }

  @Override
  public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {        
    inputFiles.forEach(this::parseFile);
    return RepeatStatus.FINISHED;
  }

  private void parseFile(File inputFile) {
    try {
      //logic here
    } catch (Exception e) {
      throw new RunTimeException(e);
    }
  }

  @Override
  public ExitStatus afterStep(StepExecution stepExecution) {
    stepExecution
        .getJobExecution()
        .getExecutionContext()
        .put("outputs", "results");
    log.info("MyTasket ended.");
    return ExitStatus.COMPLETED;
  }

Searched but most are integration tests instead of unit tests. Thanks for any help.

Eric
  • 1,031
  • 4
  • 14
  • 29

1 Answers1

0

MyTasklet is a polymorphic object, it is a Tasklet and a StepExecutionListener. So if you want to unit test it, you should unit test it in a single form (either as a Tasklet or as a StepExecutionListener).

For example, to unit test MyTasklet as a Tasklet, I would mock/stub the behaviour of it as a listener and test the behaviour of the tasklet (ie the execute method). Here is a quick example:

void testMyTasklet() throws Exception {
    // given
    ExecutionContext executionContext = ..; // // prepare execution context with files
    StepExecution stepExecution = ..; // prepare step execution with execution context
    StepContribution stepContribution = ..; // mock/stub the contribution from the step execution
    ChunkContext chunkContext = ..; // mock/stub the context as needed
    MyTasklet myTasklet = new MyTasklet();

    // when
    myTasklet.execute(stepContribution, chunkContext);

    // then
    // assert on outputs in the execution context
}

Once that in place, you can integration test it as a whole as part of a step. Spring Batch will call beforeStep/afterStep at the right time in the step lifecycle. The setup of such an integration test would be different.

Mahmoud Ben Hassine
  • 28,519
  • 3
  • 32
  • 50