Reusing expensive beans in Spring Boot Tests
Asked Answered
C

1

6

I am trying to improve performance of medium tests in Spring Boot.

I am using the Spring Boot - testcontainers library.

For an individual test this works really well, with a few annotations I can get access to kafka, zookeeper, and schema-registry. These are full services so it takes a few seconds to start everything up, all together setup takes about 40 seconds. The test accurately recreates a realistic deployment, it's beautifully simple.

This would be fine if it just happened once but it happens every time a Spring Context is created. That means every test that uses @MockBean incurs that 40 second cost.

I've tried refactoring into a single TestConfiguration class and referencing that. I've looked into using ContextHierarchy but I think that means I'll lose all of the Spring Boot niceties and I'll need to recreate the context (which means it won't look exactly like the context created by the production app).

Is there a better way to do this?

Cookbook answered 5/8, 2020 at 15:56 Comment(2)
Starting a new ApplicationContext for every test is by design. It prevents weird side effects from affecting unrelated tests. Like, what happens if a failing test left a message in kafka? It would start failing other tests. This will make it harder to pinpoint where the error is coming from.Parvati
I've recently published an article about the context caching mechanism, that my help you rieckpil.de/…. To reduce the local build times even further, you can also reuse containers with Testcontainers: rieckpil.de/…Smutchy
S
2

Spring framework already took care of this scenario.

There is a concept of caching the application context for test class/classes. See the documentation.

Few lines from the documentation:

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 run in separate processes, the static cache is cleared between each test execution, which effectively disables the caching mechanism.

So essentially you need to structure your code or context configuration in such a way that you use cached context in your desired test cases.

But use this capability wisely, if not thought through properly this could lead to undesired side-effects

Skidmore answered 6/8, 2020 at 18:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.