SpringBootTest忽略了@EnabledWebSocket

时间:2017-04-20 15:32:04

标签: 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映射不起作用。我忘记配置了什么吗?

当我使用注释为WebSocketApp.class的应用程序类(@SpringBootApplication)开始测试时,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映射。是否可以设置这种类型的映射?

2 个答案:

答案 0 :(得分:1)

就我而言,在我的Spring Boot测试类中添加@EnableAutoConfiguration,可以解决此问题。 Spring初始化DispatcherServlet并正确配置

答案 1 :(得分:0)

我找到了解决方案。在测试配置中,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));