ContextRefreshedEvent在Spring集成测试中过早发生

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ContextRefreshedEvent在Spring集成测试中过早发生相关的知识,希望对你有一定的参考价值。

我想测试像Example这样的类来处理ContextRefreshedEvent并在处理程序方法中连接到服务器:

public class Example {

    @EventListener
    public void onApplicationEvent(ContextRefreshedEvent event) {
        startWebSocketConnection();
    }

    // ...
}

但是在集成测试中,应用程序上下文是在Web套接字服务器启动并运行之前构建的,因此我得到一个异常,说连接失败(在本例中为java.net.ConnectException: Connection refused: no further information)。

测试看起来像这样:

@ExtendWith(SpringExtension.class)
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@SpringBootTest
public class WebSocketDataSourceTest {

    @Autowired 
    private Example example;

    @Autowired
    private WebSocketServer server; // created too late

    // ...
}

是否有可能抑制ContextRefreshedEvent或推迟创建应用程序上下文,以便Web套接字服务器可以在之前启动?还是有其他解决方案吗?

答案

似乎无法抑制Spring框架触发的事件或推迟创建应用程序上下文。所以我提出了以下解决方法:

import org.springframework.core.env.Environment;

public class Example {

    private boolean skipNextEvent;

    @Autowired
    public Example(Environment environment) {
        skipNextEvent = environment.acceptsProfiles("test");
    }

    @EventListener
    public void onApplicationEvent(ContextRefreshedEvent event) {
        if (skipNextEvent) {
            skipNextEvent = false;
            return;
        }
        startWebSocketConnection();
    }

    // ...
}

测试手动触发事件处理程序。

@ExtendWith(SpringExtension.class)
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@SpringBootTest
@ActiveProfiles("test") // set profile "test"
public class WebSocketDataSourceTest {

    @Autowired 
    private Example example;

    @Autowired
    private WebSocketServer server;

    @Test
    public void shouldWork() {
        // ...
        example.onApplicationEvent(null); // trigger manually
        // ...
    }
}

以上是关于ContextRefreshedEvent在Spring集成测试中过早发生的主要内容,如果未能解决你的问题,请参考以下文章

关于Spring JavaWeb工程中的ContextRefreshedEvent事件

利用ApplicationListener和ContextRefreshedEvent加载自己的beanPool

通过ContextRefreshedEvent方式初始化方法

spring容器加载完毕做一件事情(利用ContextRefreshedEvent事件)

java 应用程序启动时使用ContextRefreshedEvent(JAVA)运行一次

spring boot容器加载完后执行特定操作