spring-projects / spring-projects/spring-batch

JobScopeTestExecutionListener invokes methods with JobExecution return type

Open
#3,976 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

in: test type: bug
Dominant language
Java
Stars
3k
Forks
2.5k
Avg merge
6d 53m
Merged PRs (30d)
3

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;
    }

  }

}

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Locate org.springframework.batch.test.JobScopeTestExecutionListener and its getJobExecution(TestContext) entry point. Reproduce the issue with the supplied JobScopeTestExecutionListenerTests example, including a method returning JobExecution with arguments. Done means such utility methods are not invoked by the listener and the existing test suite still passes.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, spring
Domain
testing
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.