Traffic Parrot for MockServer users

Part of Switching from another tool, the hub for every migration page.

« Back to documentation home

An expectation and a mapping are the same idea

MockServer and Traffic Parrot describe a mock the same way: a request matcher paired with a response, with a priority when several match, a state machine when the answer depends on what came before, a delay or a fault when the test needs one, and a journal afterwards to verify what the system under test sent. If you have written MockServer expectations, a Traffic Parrot mapping reads like one with the field names changed, and the concept-mapping table is that rename.

What differs is where the mock lives and who edits it. A MockServer expectation is an object the running server holds: a test or a client library puts it there over the API, an initializer file seeds the set at start, and the dashboard shows and edits it. A Traffic Parrot mapping is a file in the selected scenario's mappings directory, created in the mapping editor, by recording real traffic, or through the management API, and kept in version control like any other file. The protocols the two reach also differ, in direction rather than in count; the next section is about when those differences start to matter.

The JSON does not carry over. A MockServer expectation is not a Traffic Parrot mapping and Traffic Parrot does not import one, so moving a mock is a translation, expectation by expectation. The worked example shows one done both ways. If your expectations were generated from an OpenAPI specification, the shortest route is to import that specification into Traffic Parrot and carry only your edits across.

Why MockServer users move to Traffic Parrot

MockServer's scope is wide and deliberate: an expectation set up from code or from its dashboard, on one port that speaks HTTP, HTTP/2, gRPC, WebSockets and raw TCP, with proxying, chaos testing and contract tooling built in. A great many teams never need more. The teams that move are the ones that hit one of these:

  • The mock is owned by people who do not write code. Both tools have a user interface; the unit it edits differs. MockServer's dashboard creates, edits and verifies expectations held by the running server. Traffic Parrot's web user interface covers the whole life of a mock as files: record real traffic into mapping files, clean them up into a flexible mock, edit the matcher, the response, the delays and faults in forms, group them into scenarios, and commit the directory. A tester or an analyst maintains that without a client library, and a developer who prefers JSON still has it.
  • The system under test speaks JMS, IBM® MQ, Thrift or files. MockServer's protocols run towards the web and towards event brokers: HTTP/1.1, HTTPS, HTTP/2, gRPC and gRPC-Web, WebSockets, raw TCP, HTTP/3 as an experiment, JSON-RPC for MCP, and Kafka, MQTT and AMQP brokers driven from an AsyncAPI specification. Traffic Parrot's run towards enterprise integration: JMS (ActiveMQ, RabbitMQ, Azure AMQP 1.0 and IBM® WebSphere MQ over JMS), native IBM® MQ, Thrift and file-based messages, alongside HTTP, SOAP, gRPC and WebSocket, in one process with one configuration model. Neither list contains the other; see Where each tool fits.
  • Recording that becomes a mock you keep, on the messaging side too. MockServer records through its proxy and replays what it recorded, and subscribes to broker channels to record messages for verification. Traffic Parrot records HTTP, gRPC, JMS queues and topics and native IBM® MQ straight into mapping files, then cleanup turns a literal recording into a mock with URL patterns, templated bodies and duplicates consolidated. See the record and replay tutorial.
  • Several teams on one server, each with its own set of mocks. MockServer's guidance for a shared deployment is one instance with a session identifier in every expectation's matcher, so one run's expectations do not answer another's requests. Traffic Parrot gives each team or environment its own scenario, a directory of mappings switched in the user interface or over the API, or its own virtual service on its own port, on one instance that developers, testers, demos, performance runs and CI agents use at the same time. Licensing is by concurrent (floating) instances.
  • Contract checks that cover messaging as well as HTTP. Both tools generate mocks from OpenAPI. Traffic Parrot also reports which operations your mocks cover, checks mappings against the specification at startup and from the command line in CI, and the command-line check reads proto files for gRPC and AsyncAPI specifications for JMS and IBM® MQ as well as OpenAPI for HTTP.

Traffic Parrot is a supported commercial product: there is a team behind it that answers questions, fixes defects and adds protocols. MockServer is Apache-2.0 licensed and free, which is the right trade for many teams; the rest of this page is for the ones whose needs have moved past what it covers.

Where each tool fits

MockServer Traffic Parrot
Protocols HTTP/1.1, HTTPS, HTTP/2, gRPC and gRPC-Web, WebSockets and raw TCP on one port; HTTP/3 as an experiment; JSON-RPC for MCP and A2A; Kafka, MQTT and AMQP brokers driven with example messages from an AsyncAPI specification, and recorded; SOAP expectations generated from a WSDL HTTP and HTTPS (HTTP/2 included), WebSocket, SOAP, gRPC, JMS, native IBM® MQ, Thrift and file-based messages, with AsyncAPI import for the messaging protocols; no Kafka, MQTT or raw TCP
Runs as Docker, Helm on Kubernetes, a JAR, a WAR or a Homebrew install; JUnit and Spring support and a Testcontainers module; clustered state for a multi-instance deployment One standalone server shared by the team and its environments: downloaded distribution, Docker image, OpenShift with a sample Helm chart, started from a build by the Maven or Gradle plugin, or from a JUnit test with the Testcontainers module
Where a mock is defined An expectation in the running server: from a client library in Java, JavaScript, Python, Ruby, Go, .NET, Rust or PHP, the REST API, the dashboard, or an initializer JSON file loaded at start and, on request, written back to The web user interface, the management API, or a JSON file per mapping dropped into the scenario's mappings directory
Recording Proxy modes (port forwarding, HTTP proxy, HTTPS tunnelling, SOCKS) that record and replay traffic; broker channels recorded for verification Recording into mapping files for HTTP, gRPC, JMS and IBM® MQ, then cleanup into a flexible mock
Dynamic responses Velocity, Mustache or JavaScript templates; callbacks to a Java class or back to the client; forwarding with overrides Handlebars templating with helpers for the request, random data, CSV and database lookups, an object store and state, plus external-process middleware and your own Java helpers and transformers
Contract tooling Expectations generated from OpenAPI or WSDL; a request matcher that names an OpenAPI operation; contract tests run against a live service; Pact import, export and verify; recorded traffic validated against a specification OpenAPI import, export, coverage, a startup check and validation in CI for HTTP, gRPC and messaging; Pact import for HTTP and message Pact import for JMS and IBM® MQ
Access control Mutual TLS, JWT or OpenID Connect on the control plane, with read, mutate and admin roles under OpenID Connect Login and roles on the web user interface and its APIs: a role that views and a role that edits
Licence and support Open source (Apache-2.0) Commercial, with support; licensed by concurrent instances

Mapping MockServer concepts onto Traffic Parrot

The MockServer column uses the field names of an expectation as the REST API and the initializer file take it, which is what you keep in version control whichever client wrote it. Every Traffic Parrot cell links to the page that documents it.

MockServer Traffic Parrot
An expectation: httpRequest, one action such as httpResponse, and id, priority, times and timeToLive around them A mapping: a request matcher, a response, a priority, one JSON file each in the selected scenario's mappings directory. The times and timeToLive fields have no counterpart: a mapping answers until it is disabled or deleted, and a one-shot answer is a scenario state that the first match moves on from.
httpRequest: method, path as a literal or a regular expression, pathParameters for the {id} segments, queryStringParameters, headers, cookies, and a body matched as a string, a regular expression, JSON, a JSON schema, JSONPath, XML or XPath The request matchers on the same parts of the request: the method, a URL matcher (an exact path, a regular expression, or a path template whose {id} segments become named variables), query parameters, headers, cookies, and body patterns with equalTo, matches, contains, equalToJson, matchesJsonPath, matchesJsonSchema, equalToXml and matchesXPath, combined with and, or and not.
priority on the expectation, where a higher number is matched first and creation order breaks a tie Priority on the mapping, where the number runs the other way: 1 is the highest and the default is 5. A catch-all gets a higher number than the specific mappings.
scenarioName, scenarioState and newScenarioState on an expectation; every scenario starts in Started Stub-level scenario state with the same shape: scenarioName, requiredScenarioState and newScenarioState on the mapping, starting in Started, and POST /api/http/__admin/scenarios/reset to put every one back. Traffic Parrot also uses the word scenario for a directory of mappings; the two are unrelated.
httpResponse: statusCode, headers, cookies, body, delay and connectionOptions The mapping's response: status, headers and body, or bodyFileName for a body kept as a file under __files, binary files included, with delays that are fixed, uniform, log-normal or a chunked dribble.
httpError with dropConnection or raw responseBytes, and the chaos features around it Faults on the mapping: a connection reset, an empty response, malformed or random data, among nine, set per mapping in the editor.
httpTemplate with a templateType of VELOCITY, MUSTACHE or JAVASCRIPT Handlebars in the response body: request data (request.path, request.query, request.headers, request.body), with JSONPath, XPath and regular-expression helpers to pick a value out, random values, conditionals and loops. For a match that no matcher expresses, a request matcher script on the mapping.
httpClassCallback to a Java class on the classpath, and httpObjectCallback back to the client that created the expectation A custom response transformer in Java, dropped into lib/external, or the external-process middleware, which hands the request and response to a program in any language. A call to another system after the response is a webhook on the mapping.
httpForward and httpOverrideForwardedRequest, and the proxy modes A proxy response on one mapping, or the passthrough proxy for a whole virtual service. When the forwarded traffic should become mappings, use recording instead; an HTTPS recording proxy covers the system under test's outbound calls.
An openAPIExpectation with specUrlOrPayload and operationsAndResponses, and an httpRequest that names an operationId OpenAPI import, which generates a mapping per operation and lets you choose the response by status code. The generated mappings match on method and URL rather than by operation id; the startup check and the validate command keep them in step with the specification, and coverage reports the operations your mocks and your traffic reach.
Verification: PUT /mockserver/verify with a matcher and times (atLeast, atMost), verifySequence, and retrieve for recorded requests The request journal over the management API: POST /api/http/requests/count and /find take a request pattern, GET /api/http/requests lists the journal in order for a sequence check, /unmatched and /unmatched/near-misses say what arrived that nothing answered. The endpoint reference lists them all.
PUT /mockserver/clear and PUT /mockserver/reset Three resets, because the state lives in three places: DELETE /api/http/requests clears the journal, POST /api/http/__admin/scenarios/reset the scenario states, DELETE /api/state the key-value state. Mappings are files, so a test that added one deletes it by id rather than resetting them all.
An initializer file (initializationJsonPath, watched with watchInitializationJson) and persistExpectations back to a file The mappings directory itself: every file in it is loaded at start, edits in the user interface and over the API are written back to it, and a file dropped in is picked up. Several sets become several scenarios, or further virtual services when each needs its own port.
The dashboard at /mockserver/dashboard: live requests, logs and active expectations, editing, clearing and verifying The web user interface: the mapping list and editor, the request log whose unmatched entries name the closest mapping and the field that did not match, and live coverage while recording.
The client libraries, the JUnit extension and the Testcontainers module The management API, documented as an OpenAPI specification for whichever client you generate; the Testcontainers module; the Maven and Gradle plugins.
Control-plane authentication: mutual TLS, JWT or OpenID Connect, with read, mutate and admin roles Login and roles on the web user interface and its APIs: one role views, one edits. HTTPS on the virtual service ports with your own certificates.
A shared, centralised deployment with a session identifier in every matcher, and clustered state One shared instance with a scenario or a virtual service per team or environment, its mapping directories in version control; no matcher needs to carry a run id, because the sets are separate.
The CRUD entity store The object store for records a request creates and later requests read back, and the data source and CSV helpers for lookups keyed by a request value.
gRPC and gRPC-Web expectations gRPC mappings from your proto files or server reflection, unary and streaming, with recording.
WebSocket expectations WebSocket mappings: a mapping fires on a message matched by its body, or on connect for a server push.
Kafka, MQTT and AMQP brokers driven and recorded from an AsyncAPI specification No Kafka or MQTT. The messaging virtual services are JMS (ActiveMQ, RabbitMQ, Azure AMQP 1.0, IBM® MQ over JMS) and native IBM® MQ, request-reply and publish-subscribe, with AsyncAPI import and recording of a real broker's traffic.
SOAP expectations generated from a WSDL SOAP over HTTP mappings, matched with the XML and XPath matchers and recorded like any HTTP traffic; no WSDL import.
Mocked chat-completion APIs, and the built-in MCP server that lets an AI coding assistant drive MockServer A chat-completion endpoint is an HTTP mapping like any other, with no provider-specific templates. Traffic Parrot serves its own MCP endpoint, so an assistant reads and changes the mappings, requests and scenarios of a running instance; see Generate mocks with an AI agent.
Mocked OAuth2, OpenID Connect, SAML and SCIM providers Plain HTTP mappings: the JWT bearer token tutorial builds a token endpoint that signs real tokens, a guarded API and a JWKS endpoint.

One expectation, both ways

A customer lookup as two MockServer expectations, in the JSON that PUT /mockserver/expectation and the initializer file take. The first answers GET /customers/123; the second is the catch-all, a regular-expression path that answers everything else under /customers/ with a 404. The specific one carries the higher priority so that it wins when both match:

{
  "httpRequest": { "method": "GET", "path": "/customers/123" },
  "httpResponse": {
    "statusCode": 200,
    "headers": { "Content-Type": ["application/json"] },
    "body": { "id": 123, "name": "Example customer" }
  },
  "priority": 10
}
{
  "httpRequest": { "method": "GET", "path": "/customers/.*" },
  "httpResponse": {
    "statusCode": 404,
    "headers": { "Content-Type": ["application/json"] },
    "body": { "error": "not found" }
  }
}

In Traffic Parrot each becomes a mapping. The specific mapping matches the exact path; the catch-all matches a path template at a lower priority, which in Traffic Parrot's numbering is the higher number, so it answers only when the specific one does not:

{
  "name": "customers: GET /customers/123",
  "request": { "method": "GET", "urlPath": "/customers/123" },
  "response": {
    "status": 200,
    "headers": { "Content-Type": "application/json" },
    "body": "{\"id\": 123, \"name\": \"Example customer\"}"
  }
}
{
  "name": "customers: GET /customers/{id} not found",
  "priority": 10,
  "request": { "method": "GET", "urlPathTemplate": "/customers/{id}" },
  "response": {
    "status": 404,
    "headers": { "Content-Type": "application/json" },
    "body": "{\"error\": \"not found\"}"
  }
}

Three things changed in the translation. The body is a string holding JSON rather than a JSON object, and the header value is a string rather than a list. The priority number runs the other way. And the regular-expression path became a path template, which is the documented way to say "any id" and gives the template {{request.path.id}} to read it back; urlPathPattern with the same regular expression would also work.

Save each as a file in the selected scenario's mappings directory, paste it into the Add/Edit mapping form, or push it through the management port with POST /api/http/__admin/mappings. Then call the virtual service port and compare with what MockServer answered:

curl -i http://localhost:8081/customers/123
curl -i http://localhost:8081/customers/999

Where the MockServer response was an httpTemplate, for example the id echoed into the body, the Traffic Parrot body reads the same value from the request: one mapping on the path template with {{request.path.id}} in the body replaces both of the above when the id is only echoed rather than looked up. The request data section lists the other fields.

Where to go next

Still weighing up the wider field rather than moving a specific MockServer setup? This page stays a migration reference. For a comparison across tools, protocols, deployment and licensing, read Best Service Virtualization Tools; for the same exercise from the WireMock, Mountebank or Mockoon side, read Traffic Parrot for WireMock users, Traffic Parrot for Mountebank users and Traffic Parrot for Mockoon users.