Reputation: 7496
For my application I created my own type of ApplicationContext
that allows me to interact in specific manners that are needed for may application. As the application is a desktop application, I create the context like this:
@SpringBootApplication
@Import(StandaloneConfiguration.class)
@PropertySource(value = {"application.properties", "server.properties"})
public class OpenPatricianApplication extends Application {
private ApplicationContext context;
@Override
public void init() {
SpringApplicationBuilder builder = new SpringApplicationBuilder(OpenPatricianApplication.class);
context = builder.contextClass(DependentAnnotationConfigApplicationContext.class).run(getParameters().getRaw().toArray(new String[0]));
// more initialisation
}
}
}
Now I want to create a Spring Boot integration test that actually relies on the functionality of my own ApplicationConext
implementation.
@SpringBootTest(classes = {ServerTestConfiguration.class})
public class ServerIntegrationTest {
private DependentAnnotationConfigApplicationContext context;
}
How do I go about initializing my context
in the test? The context
must be created in order to start the spring application for this to work, but with the SpringBootTest
annotation this already happened, when the constructor is entered.
Are there any additional annotations or parameter for existing ones that can be applied? Should tests of these nature not be annotated with SpringBootTest
at all and the application created manually?
Upvotes: 0
Views: 2087
Reputation: 7496
The approach that I found to solve this issue is to forgo the SpringBootTest
annotation altogether and construct the context as part of the constructor. Alternatively you could also do it in the BeforeAll
or BeforeEach
method, but as my test class extends a base class that needs some beans injected, the constructor seemed the right choice.
However what does not work is injecting the beans in the super class by way of constructor injection, as the call to the super constructor has to be the first call in the constructor and that would necessitate to have a static initializer block for the context and I want to avoid static stuff as much as possible, especially if the context is not properly cleaned up at the end of the test, it would live on as part of the loaded class in memory and potentially consume lot of memory.
So here is the code:
public class ServerIntegrationTest extends SaveLoadBase<CityWall> {
public CityWallSerializationTest() {
SpringApplicationBuilder builder = new SpringApplicationBuilder(ServerTestConfiguration.class);
DependentAnnotationConfigApplicationContext context = (DependentAnnotationConfigApplicationContext) builder.contextClass(DependentAnnotationConfigApplicationContext.class).run();
setContext(context);
setClientServerEventBus((AsyncEventBus) context.getBean("clientServerEventBus"));
setLoadAndSaveService(context.getBean(TestableLoadAndSaveService.class));
}
}
Upvotes: 2