title: Creating a Unit Test of a Chunk Tasklet with Mockito
body: <p>I have a <code>Chunk Tasklet</code> with a reader and writer, and I am trying to make a Unit Test for it, but I face multiples issues.</p>
  
  <p>I used the answer of the question below, to help creating my Unit Test:<br>
  <a href="https://stackoverflow.com/questions/26907419/how-define-a-spring-batch-chunk-in-the-tasklet-with-code">How define a spring batch chunk in the tasklet with code</a><br>
  Its seems to be the closest to, what I want to make.</p>
  
  <pre><code>@ContextConfiguration(locations = { "classpath:config/beans-unittest-service.xml",
          "classpath:config/beans-unittest-item.xml" })
  @RunWith(SpringJUnit4ClassRunner.class)
  public class KpiMetricFromCsvFileTaskletTest extends RegistryServiceImplTest {
  
      @Autowired
      @Qualifier("kpiMetricCsvItemReader")
      ItemReader&lt;KpiMetric&gt; reader;
  
      @Autowired
      @Qualifier("kpiMetricCreatorWriter")
      KpiMetricCreatorWriter writer;
  
      @Override
      @Before
      public void init() {
          writer.setRegistryService(registryService);
          writer.setRegistry(registry);
          setCreateKpiMeasureBehaviour();
      }
  
      private ChunkContext createChunkContext() {
          StepExecution stepExecution = Mockito.mock(StepExecution.class);
          StepContext stepContext = Mockito.mock(StepContext.class);
          ChunkContext chunkContext = Mockito.mock(ChunkContext.class);
          JobExecution jobExecution = MetaDataInstanceFactory.createJobExecution();
  
          Mockito.when(chunkContext.getStepContext()).thenReturn(stepContext);
          Mockito.when(stepContext.getStepExecution()).thenReturn(stepExecution);
          Mockito.when(stepExecution.getJobExecution()).thenReturn(jobExecution);
  
          return chunkContext;
      }
  
      @Test
      public void testTasklet() throws Exception {
          StepContribution contribution = Mockito.mock(StepContribution.class);
          ChunkContext chunkContext = createChunkContext();
  
          Tasklet tasklet = new Tasklet() {
  
              @Override
              public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
                  KpiMetric kpi = reader.read();
                  List&lt;KpiMetric&gt; items = new ArrayList&lt;&gt;();
                  while (kpi != null) {
                      items.add(kpi);
                  }
                  writer.write(items);
                  return RepeatStatus.FINISHED;
              }
          };
          tasklet.execute(contribution, chunkContext);
      }
  }
  
  </code></pre>
  
  <ul>
  <li>My Unit Test <code>Class</code> extends another <code>Class</code>, that contains methods, that will set the mock object behaviour.</li>
  <li>I have two configuration files. One of them contains a reader bean <code>kpiMetricCsvItemReader</code> and a writer bean <code>kpiMetricCreatorWriter</code>.</li>
  <li>In my Unit Test <code>init</code> method, I change the service attribute of my writer to a mock service object, I also mock the context objects, just like in the answer of the link above.</li>
  </ul>
  
  <p>The problem is that, in the <code>testTasklet</code> method, I want to create a Tasklet and execute it, but when I run the program, I get the error:</p>
  
  <blockquote>
    <p>org.springframework.batch.item.ReaderNotOpenException: Reader must be open before it can be read.</p>
  </blockquote>
  
  <p>I understand that the file is not opened, but when I launch my Job with Spring Batch, I don't get that error, so Spring should be opening my file by itself.<br>
  <br>
  Now to solve this, I should either manage to open the file for the reader or delegate the creation of the tasklet to something else, that will handle it, <strong>but how?</strong></p>
  
  <hr>
  
  <h1>EDIT</h1>
  
  <p>Perhaps showing the reader configuration file should help :</p>
  
  <pre><code>    &lt;bean id="kpiMetricCsvItemReader" class="org.springframework.batch.item.file.FlatFileItemReader"&gt;
          &lt;property name="resource" value="classpath:${kpiMetricCsvFile}" /&gt;
          &lt;property name="linesToSkip" value="1"/&gt;
          &lt;property name="lineMapper"&gt;
              &lt;bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper"&gt;
                  &lt;property name="lineTokenizer"&gt;
                      &lt;bean class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer"&gt;
                          &lt;property name="delimiter" value=";"/&gt;
                          &lt;property name="names" value="key,description,name,score,tool,variable_type" /&gt;
                      &lt;/bean&gt;
                  &lt;/property&gt;
                  &lt;property name="fieldSetMapper"&gt;
                      &lt;bean class="com.example.fieldmapper.KpiMetricFieldSetMapper" /&gt;
                  &lt;/property&gt;
              &lt;/bean&gt;
          &lt;/property&gt;
      &lt;/bean&gt;
  
      &lt;bean id="kpiMetricCreatorWriter" class="com.example.writer.kpi.KpiMetricCreatorWriter" &gt;
          &lt;property name="registry" ref="registry" /&gt;
          &lt;property name="registryService" ref="registryService" /&gt;
      &lt;/bean&gt;
  </code></pre>