Я разрабатываю API для многопользовательской игры в реальном времени и собираюсь создать интеграционные тесты для моего STOMP API. Хотя использование макетов в интеграционных тестах является необычным, я хочу убедиться, что во время определенных событий осуществляется доступ к правильным конечным точкам и методам.
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@TestPropertySource(properties = {"spring.main.allow-bean-definition-overriding=true"})
public class PublishToServerTest {
@LocalServerPort
private int port;
@MockBean
private SimpMessagingTemplate messagingTemplate;
@MockBean
private LobbyService lobbyService;
@Test
public void testPublishPlayerToLobby() throws InterruptedException {
var timeout = 3; // Seconds
var webSocketClient = new StandardWebSocketClient();
var stompClient = new WebSocketStompClient(webSocketClient);
stompClient.setMessageConverter(new MappingJackson2MessageConverter());
stompClient.setTaskScheduler(new DefaultManagedTaskScheduler());
var sessionHandler = new ExtendedStompSessionHandler() {
@Override
public void afterConnected(StompSession session, @NonNull StompHeaders connectedHeaders) {
var clientPayload = new IncomingPlayerClientPayload("0", 0);
session.send("/game/seek-opponent", clientPayload);
verify(lobbyService).matchPlayer(any());
getLatch().countDown();
}
@Override
public void handleException(@NonNull StompSession session, StompCommand command, @NonNull StompHeaders headers, @NonNull byte[] payload, @NonNull Throwable exception) {
fail(exception.getMessage());
}
};
stompClient.connectAsync(String.format("ws://localhost:%d/ws", port), sessionHandler);
var messageSent = sessionHandler.getLatch().await(timeout, TimeUnit.SECONDS);
assertTrue(messageSent);
}
LobbyService отвечает за создание новых записей в моей базе данных Firestore. Как и ожидалось, когда я имитирую этот сервис, во время теста не происходит никаких взаимодействий с базой данных, и я смогу подтвердить, что используется правильный метод. Однако вызовverify(lobbyService).matchPlayer(any()) завершается с ошибкой, означая, что взаимодействие метода не обнаруживается Mockito.
Wanted but not invoked:
lobbyService bean.matchPlayer();
Вот контроллер, который вызывает лоббиServices.matchPlayer().
@Controller
@RequiredArgsConstructor
public class LobbyController {
private final SimpMessagingTemplate messagingTemplate;
private final LobbyService lobbyService;
@MessageMapping("/seek-opponent")
public void handleIncomingUser(@Payload IncomingPlayer incomingPlayer) {
final String notificationUrl = "/lobby/notify";
lobbyService.matchPlayer(incomingPlayer).ifPresentOrElse(
multiplayerGame -> {
messagingTemplate.convertAndSendToUser(
multiplayerGame.getPlayer1().getId(),
notificationUrl,
new LobbyNotification(multiplayerGame)
);
messagingTemplate.convertAndSendToUser(
multiplayerGame.getPlayer2().getId(),
notificationUrl,
new LobbyNotification(multiplayerGame)
);
},
() -> messagingTemplate.convertAndSendToUser(
incomingPlayer.getId(),
notificationUrl,
new LobbyNotification()
)
);
}
}
Подробнее здесь: https://stackoverflow.com/questions/787 ... tion-fails