Search code examples
testingspring-batchlate-binding

Spring Batch: unit test late binding


I have reader configured as below:

<bean name="reader" class="...Reader" scope="step">
    <property name="from" value="#{jobParameters[from]}" />
    <property name="to" value="#{jobParameters[to]}" />
    <property name="pageSize" value="5"/>
    <property name="saveState" value="false" /> <!-- we use a database flag to indicate processed records -->
</bean>

and a test for it like this:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:testApplicationContext.xml"})
@ActiveProfiles({"default","mock"})
@TestExecutionListeners( {StepScopeTestExecutionListener.class })
public class TestLeadsReader extends    AbstractTransactionalJUnit4SpringContextTests {

@Autowired
private ItemStreamReader<Object[]> reader;

public StepExecution getStepExecution() {
    StepExecution execution = MetaDataInstanceFactory.createStepExecution();
    execution.getExecutionContext().putLong("campaignId", 1);
    execution.getExecutionContext().putLong("partnerId", 1);

    Calendar.getInstance().set(2015, 01, 20, 17, 12, 00);
    execution.getExecutionContext().put("from", Calendar.getInstance().getTime());
    Calendar.getInstance().set(2015, 01, 21, 17, 12, 00);
    execution.getExecutionContext().put("to", Calendar.getInstance().getTime());
    return execution;
}

@Test
public void testMapper() throws Exception {
    for (int i = 0; i < 10; i++) {
        assertNotNull(reader.read());
    }
    assertNull(reader.read());
}

Now, although the pageSize and saveState are injected correctly into my reader, the job parameters are not. According to the documentation this is all that it needs to be done and the only issues I found were about using jobParameters['from'] instead of jobParameters[from]. Any idea what could be wrong?

Also, the open(executionContext) method is not called on my reader before it enters the test method, which is not ok, because I use those job parameters to retrieve some data that needs to be available when the read method is called. This might be related to the above problem though, because the documentation concerning testing with late binding says that "The reader is initialized and bound to the input data".


Solution

  • You are setting the from and to as step execution context variables in your test. But in your application context configuration you are retrieving them as job parameters. You should set them as job parameters in your unit test.

    Also, if you want the open/update/close ItemStream lifecycle methods to be called, you should execute the step. See http://docs.spring.io/spring-batch/trunk/apidocs/org/springframework/batch/test/JobLauncherTestUtils.html#launchStep-java.lang.String-org.springframework.batch.core.JobParameters-