简体   繁体   中英

Spring integration test with custom application context

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?

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));
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM