Search code examples
spring-bootspring-batchspring-testspring-boot-test

SpringBatchTest multiple test classes - throws InstanceAlreadyExistsException


I am using @SpringBatchTest to run e2e tests on my Spring Batch application. Everything works well except when I run both of my test classes (divided my tests into positive/negative test classes) together. The first one runs and tests pass, but the second fails trying to launch the context again. Since it is already launched, the tests fail on InstanceAlreadyExistsException.

Both my test classes are defined with the following annotations:

@RunWith(SpringRunner.class)
@SpringBatchTest
@EnableAutoConfiguration
@ContextConfiguration(classes = {MyTestConfiguration.class})
@TestExecutionListeners({MockitoTestExecutionListener.class, DependencyInjectionTestExecutionListener.class, DirtiesContextTestExecutionListener.class})
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)

EDIT:

In general, what my test does is:

@RunWith(SpringRunner.class)
@SpringBatchTest
@EnableAutoConfiguration
@ContextConfiguration(classes = {HardDeleteTestConfiguration.class})
@TestExecutionListeners({MockitoTestExecutionListener.class, DependencyInjectionTestExecutionListener.class, DirtiesContextTestExecutionListener.class})
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
public class TestClass1 {
@Autowired
private JobLauncherTestUtils jobLauncherTestUtils;
@Autowired
private JobRepositoryTestUtils jobRepositoryTestUtils;

@Before
public void setUp() {
     jobRepositoryTestUtils.removeJobExecutions();
}

@Test
public void SpringBatchTest() {
    // preparing data for test
    // ...

    JobExecution jobExecution = 
    jobLauncherTestUtils.launchJob(createJobParams("myKey","myValue"));

   // Perform assertions
   // ...
}
}

private void createJobParams(String key, value) {
    JobParameters uniqueJobParameters = jobLauncherTestUtils.getUniqueJobParameters();
    JobParametersBuilder paramsBuilder = new JobParametersBuilder(uniqueJobParameters);
    paramsBuilder.addString(key, value);
    return paramsBuilder.toJobParameters();
}
}

TestClass2 is the same as TestClass1 with only different data preparation and assertions.

Also my test properties are as follows:

# Spring Boot configuration
spring.main.allow-bean-definition-overriding=true
spring.batch.job.enabled=false
# Spring Batch configuration
spring.batch.job.names=myBatchJob

I have tried all combinations of true and false for the previous flags but it does not make any difference.


Solution

  • Eventually we realized it was an in-house framework wrapping Spring that caused the problem (stupid static instantiations on context loading and such).

    To solve we used @MockBean on one problematic class, and @EnableAutoConfiguration( exclude = ProblematicConfiguration.class) in the annotation located above the test class.