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.react[email protected]3736a122

Test 2: @SpringBootTest(webEnvironment = WebEnvironment.MOCK) creates org.springframework[email protected]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?

Answer

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.