如何在Spring Test中注册ApplicationEnvironmentPreparedEvent

时间:2018-08-29 20:07:40

标签: spring spring-boot spring-test

我有一个@SpringBootTest,并且我需要通过ApplicationEnvironmentPreparedEvent通知创建一个数据库文件(如果该文件不存在),因为我的应用程序数据库试图连接到该文件并且该文件不存在。

我是通过SpringApplicationBuilder来执行此操作的,但是在JUnit中,我无法访问此构建器。这是我当前的main代码:

SpringApplicationBuilder appBuilder = new SpringApplicationBuilder();
appBuilder.headless(false);
appBuilder.listeners(new ApplicationListener<ApplicationEvent>() {
    @Override
    public void onApplicationEvent(ApplicationEvent event) {
        if (event instanceof ApplicationEnvironmentPreparedEvent) {
            Environment env = ((ApplicationEnvironmentPreparedEvent) event).getEnvironment();
            String datasourceUrl = env.getProperty(RepositoryConfig.JDBC_URL_PROPERTY);

            File db = FirebirdUtil.extractDatabaseFile(datasourceUrl);
            if (db != null) {
                String user = env.getProperty(RepositoryConfig.JDBC_USER_PROPERTY);
                String password = env.getProperty(RepositoryConfig.JDBC_PASSWORD_PROPERTY);

                // this will create the FDB file if it doesn't exists
                FirebirdUtil.createDatabaseifNotExists(db, user, password);
            }
        }
    }
});

Enviroment准备就绪时,如何通知我,以便在配置数据源之前读取JDBC URL并创建用于测试的数据库文件?

2 个答案:

答案 0 :(得分:2)

因为在测试中主要方法未运行,所以为什么您的监听器在测试中不可用。
首先,您需要提取该类的侦听器,以供将来在测试中使用(例如MyListener)。
然后使用自定义加载程序在应用程序中声明监听器。

我只是检查它是否对我有用。 这是测试示例:

@RunWith(SpringRunner.class)
@SpringBootTest
@ContextConfiguration(loader = CustomLoader.class)
public class DemoApplicationTests {

public static class CustomLoader extends SpringBootContextLoader {

    @Override
    protected SpringApplication getSpringApplication() {
        SpringApplication app = super.getSpringApplication();
        app.addListeners(new MyListener());
        return app;
    }
}

答案 1 :(得分:0)

另一种方法是利用@Import批注将ApplicationListener bean注入应用程序上下文:

@RunWith(SpringRunner.class)
@SpringBootTest
@Import(ApplicationTests.ApplicationEventListener.class)
public class ApplicationTests {

    public static class ApplicationEventListener implements ApplicationListener<ApplicationEnvironmentPreparedEvent> {
        @Override
        public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) {
            // do required staff
        }
    }
}