Skip to content

Message Verification

WireMock records all incoming messages in a journal, enabling you to verify that expected messages were received during tests. This is analogous to HTTP request verification but for message-based protocols.

The message journal records every message received by WireMock, including:

  • The message content (body)
  • The channel that received the message
  • Whether the message matched a stub
  • The stub that was matched (if any)
  • Timestamp and other metadata
import static com.github.tomakehurst.wiremock.client.WireMock.*;
import static com.github.tomakehurst.wiremock.message.MessagePattern.messagePattern;
// Verify at least one message with specific content was received
verifyMessageEvent(
messagePattern()
.withBody(equalTo("expected message"))
.build());
// Verify using regex
verifyMessageEvent(
messagePattern()
.withBody(matching("hello.*"))
.build());
// Verify exactly 3 messages were received
verifyMessageEvent(3,
messagePattern()
.withBody(matching("count-.*"))
.build());
// Verify at least 2 messages
verifyMessageEvent(moreThanOrExactly(2),
messagePattern()
.withBody(matching(".*"))
.build());
// Verify fewer than 5 messages
verifyMessageEvent(lessThan(5),
messagePattern()
.withBody(matching(".*"))
.build());
// Verify exactly N messages
verifyMessageEvent(exactly(3),
messagePattern()
.withBody(matching("test-.*"))
.build());
import static com.github.tomakehurst.wiremock.client.WireMock.*;
import static com.github.tomakehurst.wiremock.message.MessagePattern.messagePattern;
// Get all recorded messages
List<MessageServeEvent> allEvents = getAllMessageServeEvents();
// Find messages matching a pattern
List<MessageServeEvent> matchingEvents = findAllMessageEvents(
messagePattern()
.withBody(matching("find-.*"))
.build());
// Find messages by channel
List<MessageServeEvent> channelEvents = findAllMessageEvents(
messagePattern()
.withChannelPattern(
newRequestPattern().withUrl("/my-websocket"))
.build());
// Get a message event by ID
MessageServeEvent event = getMessageServeEvent(eventId);
System.out.println("Message body: " + event.getMessage().getBodyAsString());
System.out.println("Was matched: " + event.getWasMatched());
if (event.getWasMatched()) {
System.out.println("Matched stub: " + event.getStubMapping().getName());
}

Each MessageServeEvent contains:

PropertyDescription
idUnique identifier for the event
messageThe received message object
message.getBodyAsString()Message body as string
message.getBodyAsBytes()Message body as bytes
wasMatchedWhether the message matched a stub
stubMappingThe matched stub (if any)
channelRequestThe HTTP request that initiated the channel
timestampWhen the message was received

When testing asynchronous scenarios, you may need to wait for messages to arrive:

import java.time.Duration;
// Wait for a single message (returns Optional)
Optional<MessageServeEvent> event = waitForMessageEvent(
messagePattern()
.withBody(equalTo("expected"))
.build(),
Duration.ofSeconds(5));
if (event.isPresent()) {
System.out.println("Message received: " + event.get().getMessage().getBodyAsString());
} else {
System.out.println("Message not received within timeout");
}
// Wait for multiple messages
List<MessageServeEvent> events = waitForMessageEvents(
messagePattern()
.withBody(matching("batch-.*"))
.build(),
3, // expected count
Duration.ofSeconds(10));
System.out.println("Received " + events.size() + " messages");

When verification fails, WireMock throws a VerificationException with details about what was expected vs. what was received:

@Test
void verificationFailureExample() {
// This will throw VerificationException if no matching messages found
assertThrows(VerificationException.class, () ->
verifyMessageEvent(
messagePattern()
.withBody(equalTo("non-existent-message"))
.build()));
}
// Clear all recorded messages
resetMessageJournal();
// Remove a single event by ID
removeMessageServeEvent(eventId);
// Remove events matching a pattern
RemoveMessageServeEventsResult result = removeMessageServeEventsMatching(
messagePattern()
.withBody(matching("remove-.*"))
.build());
System.out.println("Removed " + result.getMessageServeEvents().size() + " events");
// Remove events for stubs matching metadata
removeMessageServeEventsForStubsMatchingMetadata(
matchingJsonPath("$.category", equalTo("test")));

You can verify whether messages matched any stubs:

List<MessageServeEvent> allEvents = getAllMessageServeEvents();
// Find unmatched messages
List<MessageServeEvent> unmatchedEvents = allEvents.stream()
.filter(event -> !event.getWasMatched())
.collect(Collectors.toList());
if (!unmatchedEvents.isEmpty()) {
System.out.println("Unmatched messages:");
for (MessageServeEvent event : unmatchedEvents) {
System.out.println(" - " + event.getMessage().getBodyAsString());
}
}

Here’s a complete test demonstrating message verification:

import static com.github.tomakehurst.wiremock.client.WireMock.*;
import static com.github.tomakehurst.wiremock.message.MessagePattern.messagePattern;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
@Test
void completeMessageVerificationExample() {
// Set up a message stub
messageStubFor(
message()
.withName("Test stub")
.withBody(matching("test-.*"))
.willTriggerActions(
sendMessage("acknowledged").onOriginatingChannel()));
// Reset the journal before the test
resetMessageJournal();
// Connect and send messages
WebSocketClient client = new WebSocketClient();
client.connect("ws://localhost:" + wireMockServer.port() + "/test");
client.sendMessage("test-1");
client.sendMessage("test-2");
client.sendMessage("other-message");
// Wait for messages to be processed
waitForMessageEvents(
messagePattern().build(), // Match any
3,
Duration.ofSeconds(5));
// Verify matched messages
verifyMessageEvent(2,
messagePattern()
.withBody(matching("test-.*"))
.build());
// Verify unmatched message
verifyMessageEvent(1,
messagePattern()
.withBody(equalTo("other-message"))
.build());
// Get all events and check match status
List<MessageServeEvent> events = getAllMessageServeEvents();
assertThat(events, hasSize(3));
long matchedCount = events.stream()
.filter(MessageServeEvent::getWasMatched)
.count();
assertThat(matchedCount, is(2L));
// Verify the matched stub name
events.stream()
.filter(MessageServeEvent::getWasMatched)
.forEach(event ->
assertThat(event.getStubMapping().getName(), is("Test stub")));
client.disconnect();
}
Java MethodDescription
verifyMessageEvent(pattern)Verify at least one message matches
verifyMessageEvent(count, pattern)Verify exact count
verifyMessageEvent(exactly(n), pattern)Verify exactly n messages
verifyMessageEvent(moreThanOrExactly(n), pattern)Verify at least n messages
verifyMessageEvent(lessThan(n), pattern)Verify fewer than n messages
getAllMessageServeEvents()Get all recorded messages
findAllMessageEvents(pattern)Find messages matching pattern
getMessageServeEvent(id)Get single event by ID
waitForMessageEvent(pattern, timeout)Wait for one message
waitForMessageEvents(pattern, count, timeout)Wait for multiple messages