Vincent Li
1 min readAug 12, 2023

4 Expiriments on @SpringBootTest context sharing

I faced a problem in my relatively new project which the Test Spring Context failed to share across different integration tests. I have an abstract class with @SpringBootTest annotation and subclasses extending this abstract class I don’t have @TestInstance(PER_CLASS) or @DirtyContext configuration but my @TestConfiguration class is created in every test. Since I have an embedded kafka server inside the TestConfiguration

Experiment 1

2 tests extending the same BaseIntegrationTest.

@ExtendWith(SpringExtension::class)
@SpringBootTest
@Import(TestProducer::class, KafkaTestConfig::class)
class BaseIntegrationTest {
}

@TestConfiguration
class KafkaTestConfig {

@Bean
fun testKafkaServer() {
EmbeddedKafkaBroker(1, true, 1).also {
it
.kafkaPorts(9092)
.afterPropertiesSet()
}
}

}

The testKafkaServer bean only initialized once

Experiment 2

Use @DirtyContext

@ExtendWith(SpringExtension::class)
@SpringBootTest
@Import(TestProducer::class, KafkaTestConfig::class)
@DirtiesContext
class BaseIntegrationTest {
}

The testKafkaServer bean initialized between tests

Experiment 3

Use @TestInstance(TestInstance.Lifecycle.PER_CLASS)

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class KafkaConsumerTest : BaseIntegrationTest() {
...
}

@ExtendWith(SpringExtension::class)
@SpringBootTest
@Import(TestProducer::class, KafkaTestConfig::class)
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class BaseIntegrationTest {
}

No issues observed in this setup, increase timeout to 10 seconds

Experiment 4

use different folder structure in test folder No issues even if I put the folder under a separate integrationTests folder, as long as it has the same root path as SpringBootApplication.kt

Conclusion

In my project, it seems the injection of mockbean which supposed to replace the actual bean in the spring test context did not happen occasionally during the integration. I could not figure out why it fails. Eventually, I stooped using @MockBean annotation and manually create a @TestConfiguration with @Bean to create the objects

In the @Configuration, I use @Profile(“!test”) to disable the loading of actual bean into context during testing

No responses yet