测试几个对 websocket 的调用
Posted
技术标签:
【中文标题】测试几个对 websocket 的调用【英文标题】:Test several calls to websocket 【发布时间】:2022-01-16 11:20:42 【问题描述】:我第一次尝试在春天跺脚。我创建了一个类似于this的端点
@MessageMapping("/game")
@SendTo("/topic/status")
public GameStatus greeting(GameMessage message, SimpMessageHeaderAccessor
headerAccessor) throws Exception
哪个(长话短说)返回持久数据。
和教程类似,我是这样测试的
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class GameIntegrationTests
@LocalServerPort
private int port;
private SockJsClient sockJsClient;
private WebSocketStompClient stompClient;
private final WebSocketHttpHeaders headers = new WebSocketHttpHeaders();
@BeforeEach
public void setup()
List<Transport> transports = new ArrayList<>();
transports.add(new WebSocketTransport(new StandardWebSocketClient()));
this.sockJsClient = new SockJsClient(transports);
this.stompClient = new WebSocketStompClient(sockJsClient);
this.stompClient.setMessageConverter(new MappingJackson2MessageConverter());
@Test
public void getGame() throws Exception
final CountDownLatch latch = new CountDownLatch(1);
final AtomicReference<Throwable> failure = new AtomicReference<>();
String[] board = "1", "2", "X", "4", "5", "6", "7", "8", "9" ;
StompSessionHandler handlerPlayer = playerHandler(latch, failure, 3, board);
this.stompClient.connect("ws://localhost:port/tictactoe-websocket", this.headers, handlerPlayer, this.port);
if (latch.await(3, TimeUnit.SECONDS))
if (failure.get() != null)
throw new AssertionError("", failure.get());
else
fail("Status not received");
private StompSessionHandler playerHandler(CountDownLatch latch, AtomicReference<Throwable> failure, Integer postion,
String[] board)
return new TestSessionHandler(failure)
@Override
public void afterConnected(final StompSession session, StompHeaders connectedHeaders)
session.subscribe("/topic/status", new StompFrameHandler()
@Override
public Type getPayloadType(StompHeaders headers)
return GameStatus.class;
@Override
public void handleFrame(StompHeaders headers, Object payload)
GameStatus gameStatus = (GameStatus) payload;
try
assertArrayEquals(board, gameStatus.getBoard());
catch (Throwable t)
failure.set(t);
finally
session.disconnect();
latch.countDown();
);
try
session.send("/app/game", new GameMessage("Spring", postion));
catch (Throwable t)
failure.set(t);
latch.countDown();
;
private class TestSessionHandler extends StompSessionHandlerAdapter
private final AtomicReference<Throwable> failure;
public TestSessionHandler(AtomicReference<Throwable> failure)
this.failure = failure;
@Override
public void handleFrame(StompHeaders headers, Object payload)
this.failure.set(new Exception(headers.toString()));
@Override
public void handleException(StompSession s, StompCommand c, StompHeaders h, byte[] p, Throwable ex)
this.failure.set(ex);
@Override
public void handleTransportError(StompSession session, Throwable ex)
this.failure.set(ex);
我想在同一个测试中测试第二次调用同一个端点来实现
boolean status= false;
StompSessionHandler handlerPlayer1 = playerHandler(latch, failure, 5, status);
关于我该怎么做的任何提示?提前致谢
【问题讨论】:
【参考方案1】:我更改了代码,它可以工作,但看起来有点矫枉过正。让我知道这看起来是否正常
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class GameIntegrationTests
@LocalServerPort
private int port;
private WebSocketStompClient stompClientPlayerOne;
private WebSocketStompClient stompClientPlayerTwo;
private final WebSocketHttpHeaders headers = new WebSocketHttpHeaders();
@BeforeEach
public void setup()
this.stompClientPlayerOne = createClient();
this.stompClientPlayerTwo = createClient();
@Test
public void getGame() throws Exception
String[] board = "1", "2", "X", "4", "5", "6", "7", "8", "9" ;
testNewConnection(board, 3, stompClientPlayerOne);
String[] board1 = "1", "2", "X", "4", "5", "6", "O", "8", "9" ;
testNewConnection(board1, 7, stompClientPlayerTwo);
private void testNewConnection(String[] board, Integer position, WebSocketStompClient stompClient)
throws InterruptedException, AssertionError
final CountDownLatch latch = new CountDownLatch(1);
final AtomicReference<Throwable> failure = new AtomicReference<>();
StompSessionHandler handlerPlayer = playerHandler(latch, failure, position, board);
stompClient.connect("ws://localhost:port/tictactoe-websocket", this.headers, handlerPlayer, this.port);
waitIfFailure(latch, failure);
private void waitIfFailure(CountDownLatch latch, AtomicReference<Throwable> failure)
throws InterruptedException, AssertionError
if (latch.await(3, TimeUnit.SECONDS))
if (failure.get() != null)
throw new AssertionError("", failure.get());
else
fail("Status not received");
private StompSessionHandler playerHandler(CountDownLatch latch, AtomicReference<Throwable> failure, Integer postion,
String[] board)
return new TestSessionHandler(failure)
@Override
public void afterConnected(final StompSession session, StompHeaders connectedHeaders)
session.subscribe("/topic/status", new StompFrameHandler()
@Override
public Type getPayloadType(StompHeaders headers)
return GameStatus.class;
@Override
public void handleFrame(StompHeaders headers, Object payload)
GameStatus gameStatus = (GameStatus) payload;
try
assertArrayEquals(board, gameStatus.getBoard());
catch (Throwable t)
failure.set(t);
finally
session.disconnect();
latch.countDown();
);
try
session.send("/app/game", new GameMessage("Spring", postion));
catch (Throwable t)
failure.set(t);
latch.countDown();
;
private WebSocketStompClient createClient()
List<Transport> transports = new ArrayList<>();
transports.add(new WebSocketTransport(new StandardWebSocketClient()));
var sockJsClient = new SockJsClient(transports);
var stompClient = new WebSocketStompClient(sockJsClient);
stompClient.setMessageConverter(new MappingJackson2MessageConverter());
return stompClient;
private class TestSessionHandler extends StompSessionHandlerAdapter
private final AtomicReference<Throwable> failure;
public TestSessionHandler(AtomicReference<Throwable> failure)
this.failure = failure;
@Override
public void handleFrame(StompHeaders headers, Object payload)
this.failure.set(new Exception(headers.toString()));
@Override
public void handleException(StompSession s, StompCommand c, StompHeaders h, byte[] p, Throwable ex)
this.failure.set(ex);
@Override
public void handleTransportError(StompSession session, Throwable ex)
this.failure.set(ex);
【讨论】:
以上是关于测试几个对 websocket 的调用的主要内容,如果未能解决你的问题,请参考以下文章
springboot websocket全套模板,省去搭建的烦恼,还有福利拿哦
springboot websocket全套模板,省去搭建的烦恼,还有福利拿哦