9

I want to be able to cache application context through different classes with tests using junit.

Test classes are declared this way:

@SpringBootTest
@RunWith(SpringRunner.class)
public class SomeIntegrationTest {
}

I saw this question Reuse spring application context across junit test classes but in this case I don't use any xml and I want to start context completely, not just few beans from it, so @SpringBootTest is more suitable than @ContextConfiguration, if I got it right.

Ruslan Akhundov
  • 2,178
  • 4
  • 20
  • 38

2 Answers2

12

Ruslan, so your question is on how to reuse the Spring Boot Context for a JUnit Suite, right?

Then, it's almost out-of-the-box provided, you just need to annotate each unit test with the @SpringBootTest annotation.

Also make sure that your main @SpringBootApplication class is loading all the necessary @Configuration classes, this process will be automatically done if the @SpringBootApplication is on the root package above all configuration class and with the inherited @ComponentScan will load up all of them.

From the Spring Boot Testing documentation:

Spring Boot provides a @SpringBootTest annotation which can be used as an alternative to the standard spring-test @ContextConfiguration annotation when you need Spring Boot features. The annotation works by creating the ApplicationContext used in your tests via SpringApplication. The Spring TestContext framework stores application contexts in a static cache. This means that the context is literally stored in a static variable. In other words, if tests execute in separate processes the static cache will be cleared between each test execution, and this will effectively disable the caching mechanism. To benefit from the caching mechanism, all tests must run within the same process or test suite. This can be achieved by executing all tests as a group within an IDE

From the Spring Testing documentation:

By default, once loaded, the configured ApplicationContext is reused for each test. Thus the setup cost is incurred only once per test suite, and subsequent test execution is much faster. In this context, the term test suite means all tests run in the same JVM

Check this urls:

Main Takeaways:

  • Annotate each unit test with @SpringBootTest

  • Load all beans and necessary configuration classes in your main @SpringBootApplication class

  • IMPORTANT: Run a JUnit Suite, not a single JUnit test. Execute all tests as a group within your IDE.

Michael Lihs
  • 7,460
  • 17
  • 52
  • 85
2

@SpringBootTest provides ApplicatonContext caching and sharing in Junit Test Cases naturally.

While some cases may be exceptions. For example, using @MockBean or @SpyBean in a test class will cause the ApplicatonContext cache failure.

While Spring’s test framework caches application contexts between tests and reuses a context for tests sharing the same configuration, the use of @MockBean or @SpyBean influences the cache key, which will most likely increase the number of contexts.

And this kind of issue is still not solved in the latest SpringBoot release.

joooohnli
  • 171
  • 1
  • 8