我有一个带有 Spring-Security/Session 和 Spring-Websocket 的 Spring Boot 2.2 MVC 应用程序。
它被配置为仅在经过身份验证时允许 websocket 连接。
以下是在单元测试中创建 Websocket 客户端的推荐方法。(至少我在 spring 文档中看到过这个)
private StompSession createWebsocket() throws InterruptedException, ExecutionException, TimeoutException {
List<Transport> transports = new ArrayList<>(1);
transports.add(new WebSocketTransport(new StandardWebSocketClient()));
WebSocketStompClient stompClient = new WebSocketStompClient(new SockJsClient(transports));
stompClient.setMessageConverter(new MappingJackson2MessageConverter());
StompSession stompSession = stompClient.connect("ws://localhost:" + port + "/app", new StompSessionHandlerAdapter() {}).get(1, SECONDS);
return stompSession;
}
Run Code Online (Sandbox Code Playgroud)
但是,这样我在日志中得到了异常,因为 Spring 重定向到登录页面,这通常是好的和需要的,因为 Websocket 请求未经身份验证。
日志确认:
2019-11-12 18:03:32.487 DEBUG 19592 --- [o-auto-1-exec-3] o.s.s.w.u.m.AndRequestMatcher : All requestMatchers returned true
2019-11-12 18:03:32.487 DEBUG 19592 …Run Code Online (Sandbox Code Playgroud) 在我的 Spring Boot 应用程序中,我也使用了 websockets。一切正常,正如在生产中预期的那样。
现在我开始使用 Spring-Boot-Test 创建单元测试。
每次我启动 @SpringBootTest 时,都会遇到以下异常(缩短):
java.lang.IllegalStateException: Failed to load ApplicationContext
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'createWebSocketContainer' defined in class path resource [com/package/spring/ws/MyWebsocketConfig.class]: Invocation of init method failed;
Caused by: java.lang.IllegalStateException: Attribute 'javax.websocket.server.ServerContainer' not found in ServletContext
Run Code Online (Sandbox Code Playgroud)
java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:125)
at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:108)
at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:190)
at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:132)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:246)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:227)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:289)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:291)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:246)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at …Run Code Online (Sandbox Code Playgroud)