Spring Boot - Web Sockets - 测试

问题描述 投票:0回答:1

我在 Spring Boot 中有一个简单的服务器。我想实现并测试我的 Web 套接字连接,但如果我想订阅端点“/topic/resources”,超时将在 30 秒后超时。消息发送正确,控制器中的函数callFunction()被调用。你知道为什么它不起作用吗?

控制器:

@Controller
public class WebSocketController {

    @MessageMapping("/{classType}/{functionName}")
    @SendTo("/topic/resources")
    public String callFunction(
            @DestinationVariable String classType,
            @DestinationVariable String functionName,
            Optional<Map<String, Object>> params
    ) {
        return classType + " " + functionName;
    }
}

配置:

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/management").withSockJS();
    }

    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        registry.setApplicationDestinationPrefixes("/call");
        registry.enableSimpleBroker("/topic");
    }
}

测试:

@SpringBootTest(classes = ManagementFrameworkApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class WebSocketTest {

    private CompletableFuture<String> completableFuture = new CompletableFuture<>();

    @LocalServerPort
    private int port;
    private final ObjectMapper objectMapper = new ObjectMapper();

    @Test
    public void testCreateGameEndpoint() throws InterruptedException, ExecutionException, TimeoutException {
        WebSocketStompClient stompClient = new WebSocketStompClient(new SockJsClient(createTransportClient()));
        stompClient.setMessageConverter(new MappingJackson2MessageConverter());

        StompSession stompSession = stompClient.connect("ws://localhost:" + port + "/management", new StompSessionHandlerAdapter() {})
                .get(5, SECONDS);

        final var params = objectMapper.createObjectNode();
        params.set("numbers", objectMapper.createArrayNode().add(1).addNull().add(2));
        params.put("operator", Operator.ADD.name());

        stompSession.subscribe("/topic/resources", new StringStompFrameHandler());
        stompSession.send("/call/CalculatorMResource/sum", params);

        String string = completableFuture.get(30, SECONDS); // here is Timeout!

        System.out.println(string);
    }

    private List<Transport> createTransportClient() {
        List<Transport> transports = new ArrayList<>(1);
        transports.add(new WebSocketTransport(new StandardWebSocketClient()));
        return transports;
    }

    private class StringStompFrameHandler implements StompFrameHandler {
        @Override
        public Type getPayloadType(StompHeaders stompHeaders) {
            return String.class;
        }

        @Override
        public void handleFrame(StompHeaders stompHeaders, Object o) {
            completableFuture.complete((String) o);
        }
    }
}
java spring testing websocket junit
1个回答
0
投票

问题在于您的测试中缺少

StringMessageConverter
WebSocketStompClient
注册。您的 websocket 端点返回一个纯字符串,
MappingJackson2MessageConverter
无法转换该字符串,因为此转换器仅负责
application/json

试试这个:

WebSocketStompClient stompClient = new WebSocketStompClient(new SockJsClient(createTransportClient()));
stompClient.setMessageConverter(new StringMessageConverter());
© www.soinside.com 2019 - 2024. All rights reserved.