Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JobScopeTestExecutionListener invokes methods with JobExecution return type #3976

Open
marschall opened this issue Aug 20, 2021 · 2 comments

Comments

@marschall
Copy link
Contributor

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

  }

}
@marschall marschall added status: waiting-for-triage Issues that we did not analyse yet type: bug labels Aug 20, 2021
@hpoettker
Copy link
Contributor

I'm afraid, it's not a bug but a feature. 😄 The javadoc on JobScopeTestExecutionListener#getJobExecution is indeed misleading but the comment on class level is correct. And it's also described in the reference documentation: https://docs.spring.io/spring-batch/docs/4.3.x/reference/html/testing.html#testing-step-scoped-components

I was also quite surprised when I stumbled on this in a similar manner, and I'm not sure whether it's a good idea that the listeners are added with @SpringBatchTest automatically. In particular, since there is no straight-forward way to disable them, if I still want the beans from BatchTestContextCustomizer.

Maybe an annotation like e.g. @TestJobExecution on the method would be a sensible requirement for users to enable this feature.

@fmbenhassine fmbenhassine added in: test and removed status: waiting-for-triage Issues that we did not analyse yet labels Sep 8, 2021
@mbracero
Copy link

mbracero commented Feb 6, 2025

As a temporary workaround I added the following annotation to my test class:

@TestExecutionListeners( listeners = {}, mergeMode = TestExecutionListeners.MergeMode.MERGE_WITH_DEFAULTS )

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants