Open
Description
Bug description
JobScopeTestExecutionListener
invokes any method with the JobExecution
return type. Consider the following test with uses a utility method to launch a job. The method will be invoked by JobScopeTestExecutionListener
before the @BeforeEach
and @Test
method. In this case causing the test to fail because the jobParameters
is null
.
class MyBatchTests {
private JobParameters jobParameters;
@BeforeEach
void setUp() {
this.jobParameters = ...;
}
private JobExecution launchJobUtilityMethod() throws Exception {
return this.jobLauncherTestUtils.launchJob(this.jobParameters);
}
@Test
void batchTest() throws Exception {
JobExecution jobExecution = this.launchJobUtilityMethod();
assert...;
}
}
Environment
Spring Batch version: 4.3.3
Java version: 11.0.12
Database: H2 1.4.200
Steps to reproduce
- Create a test with a
JobScopeTestExecutionListener
, for example by adding@SpringBatchTest
- Add a method with return type
JobExecution
, can have any number of arguments
Expected behavior
org.springframework.batch.test.JobScopeTestExecutionListener#getJobExecution(TestContext)
looks only at fields as the comment says.
Minimal Complete Reproducible example
@SpringBatchTest
class JobScopeTestExecutionListenerTests {
private JobExecution shouldNeverBeInvoked(String s, int i) {
throw new IllegalStateException("should never be invoked");
}
@Test
void testMethod() throws Exception {
}
@Configuration
@EnableBatchProcessing
static class ContextConfiguration {
private static final Log LOGGER = LogFactory.getLog(MethodHandles.lookup().lookupClass());
@Autowired
public JobBuilderFactory jobBuilderFactory;
@Autowired
public StepBuilderFactory stepBuilderFactory;
@Bean
public Job loggingJob() {
return this.jobBuilderFactory.get("loggingJob")
.incrementer(new RunIdIncrementer())
.start(this.step1())
.build();
}
@Bean
public Step step1() {
return this.stepBuilderFactory.get("step1")
.tasklet(this.loggingTasklet("step1"))
.build();
}
@Bean
public DataSource dataSource() {
return new EmbeddedDatabaseBuilder()
.generateUniqueName(true)
.setType(H2)
.build();
}
private Tasklet loggingTasklet(String stepName) {
CallableTaskletAdapter taskletAdapter = new CallableTaskletAdapter();
taskletAdapter.setCallable(() -> {
LOGGER.info("executing step: " + stepName);
return RepeatStatus.FINISHED;
});
return taskletAdapter;
}
}
}