Search code examples
javaspringspring-bootspring-boot-test

Running spring boot tests parallelly using gradle create two application contexts


We have 2 spring boot integration tests runnig on Netty.

We use gradle to run tests parallelly using flag: org.gradle.parallel=true

Test 1: @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) creates org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext@3736a122

Test 2: @SpringBootTest(webEnvironment = WebEnvironment.MOCK) creates org.springframework.boot.web.reactive.context.GenericReactiveWebApplicationContext@45fa13a7

Two application contexts are created and one of the application contexts randomly is injected to production code and as a result we have two sets of beans.

The following dependencies are used:

dependencySet(group: 'org.springframework', version: '5.3.5')

dependencySet(group: 'org.springframework.boot', version: '2.4.4')

Is is ok behaviour, because in one case: mock web environment is used and in another real web environment?


Solution

  • When utilizing the Spring Test Context Framework it will do context caching. When the same context configuration is used it will re-use an existing context (or start one if not already there). If there is a new configuration combination (in your case there is a difference in the runtime i.e. start a real server or use a mock environment) it will start a new one.

    From the aforementioned reference guide:

    An ApplicationContext can be uniquely identified by the combination of configuration parameters that are used to load it. Consequently, the unique combination of configuration parameters is used to generate a key under which the context is cached. The TestContext framework uses the following configuration parameters to build the context cache key:

    • locations (from @ContextConfiguration)
    • classes (from @ContextConfiguration)
    • contextInitializerClasses (from @ContextConfiguration)
    • contextCustomizers (from ContextCustomizerFactory) – this includes @DynamicPropertySource methods as well as various features from Spring Boot’s testing support such as @MockBean and @SpyBean.
    • contextLoader (from @ContextConfiguration)
    • parent (from @ContextHierarchy)
    • activeProfiles (from @ActiveProfiles)
    • propertySourceLocations (from @TestPropertySource)
    • propertySourceProperties (from @TestPropertySource)
    • resourceBasePath (from @WebAppConfiguration)

    In this case, due to the different runtime, there is a difference in the contextCustomizers and thus no cached context is available and a new one will be started.