Reusing application context across tests — @DirtiesContex… — Cracked Java
// Spring Framework & Spring Boot · Testing — Unit, Slice, Integration
SeniorTheoryBig Tech

Reusing application context across tests — @DirtiesContext vs sharing.

Spring's TestContext framework caches each unique ApplicationContext and reuses it across every test class with the same configuration — so in a well-designed suite the context starts a handful of times, not once per class. Understanding this cache is the difference between a 30-second suite and a 10-minute one.

How the cache works

The cache key is the configuration: which classes/locations, active profiles, properties, the set of @MockitoBeans, web environment, initializers, and so on. If two test classes resolve to the same key, the second reuses the first's context — no second startup. Change any keyed attribute and you get a different key → a new context built and cached (the default cache holds up to 32 contexts, LRU-evicted).

The practical implication: minimize distinct configurations. A suite where every test uses the same base @SpringBootTest setup builds one context; a suite where each class tweaks properties or mocks different beans fragments the cache and rebuilds repeatedly.

// These two classes SHARE one cached context (identical config):
@SpringBootTest class OrderFlowTest { }
@SpringBootTest class PaymentFlowTest { }

// This one gets its OWN context (different mock set changes the key):
@SpringBootTest class RefundTest {
    @MockitoBean FraudCheck fraud;
}

@DirtiesContext — the cache buster

@DirtiesContext tells Spring the context is now polluted and must be closed and rebuilt for the next test. You apply it (per class or per method) when a test mutates shared singleton state in a way later tests can't tolerate — a modified bean, a cache you can't reset, a started scheduler.

@DirtiesContext(methodMode = MethodMode.AFTER_METHOD)
@Test void mutatesSingletonState() { /* forces a fresh context after */ }

The cost is real: every @DirtiesContext discards a cached context and pays full startup again, and can knock other tests' shared context out of the cache. Treat it as a last resort.

Prefer cleanup over rebuild

Most "I need @DirtiesContext" situations are better solved by resetting state instead of trashing the context:

  • Reset mocks with Mockito.reset(...) or rely on @MockitoBean's per-method reset.
  • Roll back DB changes with @Transactional (as @DataJpaTest does) or use Testcontainers with per-test cleanup.
  • Clear caches/in-memory state in an @AfterEach.

Mark your status