2017-07-14 1196 views
1

我正在開發Spring Boot Server項目,該項目提供了簡單的REST資源,直到現在。爲了將通知推送到客戶端,我想添加一個websocket連接。爲了測試這方面,我已經使用基於本教程SockJS客戶端寫的集成測試:Spring Boot WebSocket在SockJS客戶端測試中拋出「拒絕連接」

http://rafaelhz.github.io/testing-websockets/

問題是連接與以下錯誤拒絕:

org.springframework.web.client.ResourceAccessException: I/O error on GET request for "http://localhost:9090/websocket/info": Connection refused (Connection refused); nested exception is java.net.ConnectException: Connection refused (Connection refused) 

我的WebSocket配置如下:

import org.springframework.context.annotation.Configuration; 
import org.springframework.messaging.simp.config.MessageBrokerRegistry; 
import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer; 
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker; 
import org.springframework.web.socket.config.annotation.StompEndpointRegistry; 

@Configuration 
@EnableWebSocketMessageBroker 
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer { 

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

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

} 

我可以看到,在套接字端點映射到日誌:

2017-07-14 15:22:59.561 INFO 13765 --- [   main] o.s.w.s.s.s.WebSocketHandlerMapping  : Mapped URL path [/websocket/**] onto handler of type [class org.springframework.web.socket.sockjs.support.SockJsHttpRequestHandler] 

服務器端口設置爲9090在application.yml文件:

server: 
port: 9090 

下面的單元測試是無法連接到插座:

import org.junit.Assert; 
import org.junit.Before; 
import org.junit.Test; 
import org.junit.runner.RunWith; 
import org.springframework.boot.test.context.SpringBootTest; 
import org.springframework.test.annotation.DirtiesContext; 
import org.springframework.test.context.ActiveProfiles; 
import org.springframework.test.context.junit4.SpringRunner; 
import org.springframework.web.socket.client.standard.StandardWebSocketClient; 
import org.springframework.web.socket.messaging.WebSocketStompClient; 
import org.springframework.web.socket.sockjs.client.SockJsClient; 
import org.springframework.web.socket.sockjs.client.WebSocketTransport; 
import org.springframework.messaging.simp.stomp.StompFrameHandler; 
import org.springframework.messaging.simp.stomp.StompHeaders; 
import org.springframework.messaging.simp.stomp.StompSession; 
import org.springframework.messaging.simp.stomp.StompSessionHandlerAdapter; 

import java.lang.reflect.Type; 
import java.util.concurrent.BlockingQueue; 
import java.util.concurrent.LinkedBlockingDeque; 

import static java.util.Arrays.asList; 
import static java.util.concurrent.TimeUnit.SECONDS; 

@RunWith(SpringRunner.class) 
@SpringBootTest 
@ActiveProfiles("test") 
//@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD) 
public class WebSocketConnectionTest { 

    static final String WEBSOCKET_URI = "ws://localhost:9090/websocket"; 
    static final String WEBSOCKET_TOPIC = "/topic"; 

    BlockingQueue<String> blockingQueue; 
    WebSocketStompClient stompClient; 

    @Before 
    public void setup() { 
     blockingQueue = new LinkedBlockingDeque<>(); 
     stompClient = new WebSocketStompClient(new SockJsClient(
       asList(new WebSocketTransport(new StandardWebSocketClient())))); 

     System.out.println(WEBSOCKET_URI); 
    } 

    @Test 
    public void shouldReceiveAMessageFromTheServer() throws Exception { 
     StompSession session = stompClient 
       .connect(WEBSOCKET_URI, new StompSessionHandlerAdapter() {}) 
       .get(1, SECONDS); 
     session.subscribe(WEBSOCKET_TOPIC, new DefaultStompFrameHandler()); 

     String message = "MESSAGE TEST"; 
     session.send(WEBSOCKET_TOPIC, message.getBytes()); 

     Assert.assertEquals(message, blockingQueue.poll(1, SECONDS)); 
    } 

    class DefaultStompFrameHandler implements StompFrameHandler { 
     @Override 
     public Type getPayloadType(StompHeaders stompHeaders) { 
      return byte[].class; 
     } 

     @Override 
     public void handleFrame(StompHeaders stompHeaders, Object o) { 
      blockingQueue.offer(new String((byte[]) o)); 
     } 
    } 
} 

連接被拒絕。我相當肯定,這是因爲URI端點不存在,但我不知道爲什麼。有人知道URI中是否有錯誤,或者是否有其他內容導致拒絕連接?

+0

您是否從Sock js調用端點? –

+0

我在失敗的集成測試中使用SockJS Java Client調用端點。這是你要求的嗎? – TardigradeX

回答

3

我發現問題的原因。 PORT 9090上不存在端點。這是因爲@SpringBootTest註釋默認情況下將Web環境設置爲WebEnvironment.MOCK。在這個配置中,沒有嵌入式Servlet被啓動並且因此沒有端口存在,只有基於MockMvc的測試是可能的。爲了啓動嵌入式Servlet ,環境必須設置爲WebEnvironment.RANDOM_PORTWebEnvironment.DEFINED_PORT。我將它設置爲DEFINED_PORT,以便使用我的application.yml中的端口9090。通過設置環境,測試運行正確。

@RunWith(SpringRunner.class) 
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)//!!!!! 
@ActiveProfiles("test") 
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD) 
public class WebSocketConnectionTest { 

String WEBSOCKET_URI = "ws://localhost:9090/websocket"; 
String WEBSOCKET_TOPIC = "/topic"; 
. 
. 
. 
相關問題