测试对websocket的几个调用



我第一次尝试在春天踩踏。我创建了一个类似于这个的端点

@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);

有什么关于我该怎么做的提示吗?提前感谢

我更改了代码,它可以工作,但看起来有些过头了。让我知道这看起来是否正常

@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);
}
}
}

最新更新