Part of Switching from another tool, the hub for every migration page.
« Back to documentation homeMockoon and Traffic Parrot start from the same conviction: a mock API should be something you build and read in a user interface, not only in code. If you have been mocking in Mockoon, the way you think about a mock carries over. A route with a method, a path and a response, rules that pick a response from the request, a body that is templated from the request, and a proxy that forwards what you have not mocked yet all have a direct counterpart in Traffic Parrot's mapping editor.
What differs is where the mock runs and what it can speak. Mockoon is a desktop application (with a command-line runner and a Docker image for headless use) that mocks HTTP, HTTPS and WebSocket, and it is very good at that on one developer's machine. Traffic Parrot is a standalone server built to be shared by a team and by every environment in a delivery pipeline, and it virtualises the messaging and RPC protocols enterprise systems depend on in the same instance as HTTP. The next section is about when those two differences start to matter.
The JSON does not carry over. A Mockoon environment file is not a Traffic Parrot mapping and Traffic Parrot does not import one, so moving a mock is a translation, route by route. The concept-mapping table is that translation and the worked example shows one route done both ways. If your Mockoon environment was generated from an OpenAPI specification, or you have exported one, the shortest route is to import the specification into Traffic Parrot and carry only your edits across.
Mockoon's scope, one machine and HTTP, is a design choice rather than a shortcoming, and a great many teams never need more. The teams that move are the ones that hit one of these:
Traffic Parrot is a supported commercial product: there is a team behind it that answers questions, fixes defects and adds protocols. Mockoon is MIT-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 one desktop.
| Mockoon | Traffic Parrot | |
|---|---|---|
| Protocols | HTTP, HTTPS and WebSocket routes | HTTP and HTTPS (HTTP/2 included), WebSocket, SOAP, gRPC, JMS, native IBM® MQ, Thrift and file-based messages |
| Runs as | A desktop application per developer; a command-line runner and Docker image for headless use; hosted deployments through Mockoon Cloud | One standalone server shared by the team and its environments: downloaded distribution, Docker image, OpenShift, started from a build by the Maven or Gradle plugin, or from a JUnit test with the Testcontainers module |
| Where a mock is defined | The desktop user interface, saved as one JSON file per environment | The web user interface, the management API, or a JSON file per mapping dropped into the scenario's mappings directory |
| Recording | Proxy mode with request logs; a logged request can become a route | Recording into mapping files, then cleanup into a flexible mock |
| Dynamic responses | Handlebars-style templating with helpers for the request, random data, data buckets and global variables | 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 |
| Contract tooling | OpenAPI import and export | OpenAPI import, export, coverage and validation in CI |
| Licence and support | Open source (MIT); Mockoon Cloud is a subscription | Commercial, with support; licensed by concurrent instances |
The Mockoon column uses the names from its environment file, which is what you export or keep in version control. Every Traffic Parrot cell links to the page that documents it.
| Mockoon | Traffic Parrot |
|---|---|
An environment: port, hostname,
endpointPrefix, a list of routes |
The HTTP virtual service on trafficparrot.virtualservice.http.port
(8081 by default, see the
configuration reference), serving every mapping in
the selected scenario. Several environments
become several scenarios, switched in the user interface or over the API, or
further virtual services when each
needs its own port.
|
A route: method, endpoint with
:param segments, a list of responses |
A mapping: a
request matcher (method plus a URL matcher: a
path template or a
regular expression where the route
had a parameter) and one response. A route with
several responses becomes one mapping per response, each carrying the matcher
that response's rules described.
|
Response rules on body, query,
header, cookie, params, path
and method, with equals, regex,
regex_i, null, empty_array,
array_includes and valid_json_schema, joined by
rulesOperator |
Request matchers on the same parts of the
request: equalTo, matches (a regular expression),
absent, matchesJsonPath, matchesJsonSchema,
equalToJson and the rest of the
matchers reference, combined
with and,
or and not.
|
A rule on request_number, or the route's responseMode set
to SEQUENTIAL |
Stub-level scenario state: the
mappings in the sequence share a scenarioName, each has its
requiredScenarioState, and each moves the sequence on with
newScenarioState. The state is explicit, so a test can read it back
and reset it rather than counting calls.
|
responseMode set to RANDOM |
One mapping whose body picks with the random value helpers, or a scenario state sequence when the order matters to the test. |
The response marked default, responseMode
FALLBACK, and fallbackTo404 |
A catch-all mapping with a lower priority than the specific ones (the default priority is 5, and 1 is the highest). A request that no mapping matches gets an HTTP 900 response and a near-miss entry in the request log saying which mapping almost matched and why it did not. |
A response's statusCode, headers and body,
or bodyType FILE with a filePath |
The mapping's response: status, headers and
body, or bodyFileName for a body kept as a
file under __files,
binary files included.
|
latency on a response or on the environment |
Delays on the mapping: fixed, uniform or log-normal, and a chunked dribble that spreads the body over time, next to nine faults such as a connection reset or an empty response. |
Templating helpers such as urlParam, queryParam,
header and body |
Request data in the template:
request.path, request.query,
request.headers and request.body, with
JSONPath,
XPath and
regular-expression helpers to pick a
value out.
|
The faker helper |
The random value helpers: identifiers, numbers, dates and strings of a given shape. |
Data buckets, and the data helper that reads them |
The CSV and data source helpers for lookups keyed by a request value, and the object store for records a request creates and later requests read back. |
CRUD routes backed by a data bucket, and crudKey |
A mapping per operation whose template uses the
object store: create from the
request body, get, set and put by id, one
file per record under the files root's data directory.
|
Global variables: setGlobalVar and
getGlobalVar, and a rule on global_var |
The state helper: set, get and add to a
named value across requests, read and reset from the management port with the
/api/state endpoints described there.
|
A rule on templating |
A request matcher script on the mapping, for a match that no matcher expresses. |
| Callbacks sent after a response | Webhook callbacks on the mapping, sent to a URL after the response. |
proxyMode with proxyHost, proxyReqHeaders
and proxyResHeaders |
The passthrough proxy for a whole virtual service, or a proxy response on one mapping. When the forwarded traffic should become mappings, use recording instead. |
| The request logs, and creating a route from a logged request |
The request log, in the user interface and
over the API (GET /api/http/requests). An unmatched entry names the
closest mapping and the field that did
not match, with a link into that mapping's editor, and
request verification serves tests. To
turn traffic into mappings, record it.
|
Environment headers added to every response, and cors |
Response headers per mapping, and CORS-friendly responses that are on out of the box. |
tlsOptions on the environment |
The HTTPS virtual service port and its certificates, and per virtual service. |
WebSocket routes (type ws) with a streaming mode |
WebSocket mappings: a mapping fires on a message matched by its body, or on connect for a server push. |
| The Mockoon CLI and Docker image for CI | Start the distribution, run the Docker image, start and stop it from a build with the Maven or Gradle plugin, or inside a JUnit test with the Testcontainers module. |
| Mockoon Cloud synchronisation between team members | One shared instance, with its mapping directories in version control, and virtual services to give each team or environment its own set of mappings on the same server. |
A customer lookup as it appears inside a Mockoon environment file: one route,
GET customers/:id, with two responses. The first answers when the
id parameter is 123; the second is the default and answers everything
else with a 404. The environment fields around the route, and the generated
uuid values, are left out.
{
"type": "http",
"method": "get",
"endpoint": "customers/:id",
"responses": [
{
"statusCode": 200,
"headers": [{ "key": "Content-Type", "value": "application/json" }],
"body": "{\"id\": 123, \"name\": \"Example customer\"}",
"rules": [{ "target": "params", "modifier": "id", "operator": "equals", "value": "123" }],
"rulesOperator": "OR",
"default": false
},
{
"statusCode": 404,
"headers": [{ "key": "Content-Type", "value": "application/json" }],
"body": "{\"error\": \"not found\"}",
"rules": [],
"default": true
}
],
"responseMode": null
}
In Traffic Parrot each response is its own mapping, and the rule becomes the request matcher. The specific mapping matches the exact path; the catch-all matches the path template at a lower priority, 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\"}"
}
}
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 Mockoon answered:
curl -i http://localhost:8081/customers/123
curl -i http://localhost:8081/customers/999
Where the Mockoon body was templated, for example
{{urlParam 'id'}} echoed into the JSON, the Traffic Parrot body reads the same
value from the request: one mapping on the path template with
{{request.path.id}} in the body, the named path variable, replaces both of the
above when the id is only echoed rather than looked up. The
request data section lists the other fields.
Still weighing up the wider field rather than moving a specific Mockoon 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 or Mountebank side, read Traffic Parrot for WireMock users and Traffic Parrot for Mountebank users.