Skip to content

WebSockets

WireMock provides native support for mocking WebSocket connections, enabling comprehensive testing of real-time, bidirectional communication in your applications.

WebSocket mocking in WireMock allows you to:

  • Accept WebSocket connections on any URL path
  • Stub message responses based on incoming message content
  • Broadcast messages to multiple connected clients
  • Verify messages received during tests
  • Send messages programmatically via the Admin API

It is based on WireMock’s message-based mocking framework.

WebSocket support is enabled by default in WireMock. No additional configuration is required.

import static com.github.tomakehurst.wiremock.client.WireMock.*;
messageStubFor(
message()
.withName("Echo stub")
.withBody(matching(".*"))
.willTriggerActions(
sendMessage("Echo: {{message.body}}")
.onOriginatingChannel()));
WebSocketClient client = new WebSocketClient();
client.connect("ws://localhost:8080/echo");
String response = client.sendMessageAndWaitForResponse("Hello!");
// response = "Echo: Hello!"

Match incoming messages using any of WireMock’s powerful matchers:

// Exact match
message().withBody(equalTo("ping"))
// Regex pattern
message().withBody(matching("hello.*"))
// JSON path
message().withBody(matchingJsonPath("$.action", equalTo("subscribe")))

Control which channels receive response messages:

// Send to the channel that sent the message
sendMessage("response").onOriginatingChannel()
// Broadcast to all channels matching a pattern
sendMessage("notification")
.onChannelsMatching(newRequestPattern().withUrl(urlPathMatching("/broadcast/.*")))

Use Handlebars templates in message responses:

sendMessage("Hello {{jsonPath message.body '$.name'}}, welcome!")
.onOriginatingChannel()

Configure WebSocket behavior using these options:

OptionJavaCLIDefault
Idle timeout.webSocketIdleTimeout(ms)--websocket-idle-timeout300000 (5 min)
Max text message size.webSocketMaxTextMessageSize(bytes)--websocket-max-text-message-size10485760 (10MB)
Max binary message size.webSocketMaxBinaryMessageSize(bytes)--websocket-max-binary-message-size10485760 (10MB)

Example:

WireMockServer wm = new WireMockServer(
wireMockConfig()
.port(8080)
.webSocketIdleTimeout(600000) // 10 minutes
.webSocketMaxTextMessageSize(1048576)); // 1MB

For comprehensive documentation on WebSocket mocking, see the Message-Based Mocking section:

EndpointMethodDescription
/__admin/message-mappingsGETList all message stubs
/__admin/message-mappingsPOSTCreate a message stub
/__admin/message-mappings/{id}DELETERemove a message stub
/__admin/messagesGETGet all received messages
/__admin/messagesDELETEClear message journal
/__admin/channelsGETList active channels
/__admin/channels/sendPOSTSend message to channels
@Test
void chatRoomSimulation() {
// Set up message stub for broadcasting
messageStubFor(
message()
.withName("Chat broadcast")
.onWebsocketChannelFromRequestMatching("/chat")
.withBody(matchingJsonPath("$.type", equalTo("message")))
.willTriggerActions(
sendMessage("{{message.body}}")
.onChannelsMatching(
newRequestPattern().withUrl("/chat"))));
// Connect two clients
WebSocketClient alice = new WebSocketClient();
WebSocketClient bob = new WebSocketClient();
alice.connect("ws://localhost:" + wm.port() + "/chat");
bob.connect("ws://localhost:" + wm.port() + "/chat");
// Wait for connections
await().until(() -> alice.isConnected() && bob.isConnected());
// Alice sends a message
alice.sendMessage("{\"type\": \"message\", \"from\": \"Alice\", \"text\": \"Hi Bob!\"}");
// Both Alice and Bob receive it (including sender)
await().until(() ->
alice.getMessages().stream().anyMatch(m -> m.contains("Hi Bob!")) &&
bob.getMessages().stream().anyMatch(m -> m.contains("Hi Bob!")));
// Verify message was recorded
verifyMessageEvent(
messagePattern()
.withBody(matchingJsonPath("$.from", equalTo("Alice")))
.build());
}