java - SpringBootTest @EnabledWebSocket 忽略

标签 java spring spring-boot spring-websocket spring-boot-test

我想测试我的 WebSocket 应用程序。

测试类:

@RunWith(SpringRunner.class)
@SpringBootTest(
    webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
@ContextConfiguration(
    classes = {WebConfig.class, WebSocketConfig.class}
@DirtiesContext
public class IntegrationTest {

    @Autowired
    public EmbeddedWebApplicationContext server;   

    @Test
    ...
}

WebConfig 类:

@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {

    public final WebSocketService webSocketService;

    @Autowired
    public WebConfig(WebSocketService webSocketService) {
        this.webSocketService = webSocketService;
    }

    @Bean
    public EmbeddedServletContainerFactory servletContainer() {
        TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory();
        tomcat.setPort(1234);
        tomcat.setContextPath("/test");

        return tomcat;
    }
}

和 WebSocketConfig 类:

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {

    @Autowired
    public WebSocketConfig() {}                     

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry webSocketHandlerRegistry) {        

        webSocketHandlerRegistry.addHandler(webSocketHandler(), "ws")                
            .setAllowedOrigins("*")                
    }

    @Bean
    public WebSocketHandler webSocketHandler() {
        return new WebsocketHandler(webSocketService());
    }

    @Bean
    publicWebSocketService webSocketService() {
        return newWebSocketServiceImpl();
    }
}

当我开始测试时,Tomcat 正在启动并监听指定端口 1234。但我无法连接 websocket 客户端。 WebSocketConfig 被调用。但我认为 websocket 映射不起作用。我忘记配置什么了吗?

当我开始测试用 @SpringBootApplication 注释的应用程序类 (WebSocketApp.class) 时,websocket 映射工作正常。

@RunWith(SpringRunner.class)
@SpringBootTest(
    webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
@ContextConfiguration(
    classes = {WebSocketApp.class}
@DirtiesContext
public class IntegrationTest {

    @Autowired
    public EmbeddedWebApplicationContext server;   

    @Test
    ...
}

WebSocketApp 也使用相同的配置。

我假设第二种方法有效,因为使用了 @EnableWebSocket。当我不使用 WebSocketApp.class(用 @SpringBootApplication 注释)时,@EnableWebSocket 将被忽略。

有没有人有让测试运行的想法?如何在没有注释的情况下手动启用 websockets?

编辑:

我发现,TomcatEmbeddedContext 使用默认的 servlet 映射而不是 dispatcherServlet 映射。是否可以设置这种类型的映射?

最佳答案

我找到了一个解决方案。在测试配置中,Spring 没有引导 websocket 容器和 servlet 映射。

我不得不添加一些额外的配置:

@Bean
    public ServletServerContainerFactoryBean createWebSocketContainer() {
        ServletServerContainerFactoryBean container = new ServletServerContainerFactoryBean();
        container.setMaxTextMessageBufferSize(8192);
        container.setMaxBinaryMessageBufferSize(8192);
        return container;
    }

    @Bean
    public DispatcherServlet dispatcherServlet() {
        return new DispatcherServlet();
    }

    @Bean
    public ServletRegistrationBean dispatchServletRegistration() {

        ServletRegistrationBean registration = new ServletRegistrationBean(
            dispatcherServlet(), "/");

        registration
            .setName(DispatcherServletAutoConfiguration.DEFAULT_DISPATCHER_SERVLET_BEAN_NAME);

        return registration;

    }

然后到 EmbeddedServletContainerFactory bean:

tomcat.addContextCustomizers((TomcatContextCustomizer) context ->
            context.addServletContainerInitializer(new WsSci(), null));

关于java - SpringBootTest @EnabledWebSocket 忽略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43523949/

相关文章:

Java TL1协议(protocol)

java - Spring,@Transactional 和 Hibernate 延迟加载

java - 在 Spring Data MongodB 存储库中查询集合内的字符串

java - 对于 5 个构造函数参数中的 2 个,Postman 对 spring 的 post 调用始终为 null

java - 如何在 spring data jpa 中为自定义采石场提供可变参数而不使用 for 循环

java - Jackson 在 Spring Boot 中错误地序列化了 ZonedDateTime

java - Android 应用程序无异常退出

java - 使用 org.json 保持 JSON 文件键的顺序?

elasticsearch - 我可以在Spring Data ElasticSearch中使用唯一组合字段吗?

java - ClassName.m() 和 (new ClassName()).m() 有什么区别 m() 是静态方法