Mock services
A mock service answers requests for an interface or an API before the real one exists, or while it is down. It is made from the contract you imported, checks each request against it, and answers with responses you write. Every response is a file in the project, so a mock is reviewed and shared like the requests beside it.
Make a mock
Section titled “Make a mock”- Right-click an interface or an imported REST API in the explorer and choose New Mock. For a WSDL with more than one binding, right-click the binding instead and choose New Mock of this binding.
- The mock opens in its own tab, and appears under Mocks in the project. It has one operation for
each operation of the contract, each with a response named
Default: a sample of the operation’s output for SOAP, and the lowest documented 2xx with its example (or a sample of its schema) for REST. - Choose Start. The tab shows the mock’s URL, with Copy; point a request or your own client at it.
The mock is made from the definition Wirebench cached when you imported it, so making one and running one never use the network. An interface or API imported without a cached definition can’t be mocked until you import it again with definitions cached.
Settings
Section titled “Settings”| Setting | What it does |
|---|---|
| Port | The port to listen on. 0 picks a free one when the mock starts, and keeps it while the mock is edited |
| Path | Where the mock is served. A SOAP mock also serves its WSDL at <path>?wsdl, with every address rewritten to the mock |
| Contract check | Refuse a request that breaks the contract answers it with a SOAP fault or a 4xx; Answer anyway and log the problems dispatches it and lists the problems in the log; Do not check requests only routes it |
A running mock picks up an edit at once: it restarts with the new settings, on the same port.
Pick a response
Section titled “Pick a response”Select an operation to see its responses and choose how it picks one (Dispatch):
| Dispatch | Picks |
|---|---|
| In order | The next response each time, back to the first after the last |
| At random | Any response |
| By match conditions | The first response whose conditions all hold. A response with none matches anything, so put it last as a catch-all |
| By script | The response a script names |
When nothing is picked, the operation’s Default response is sent.
A match condition reads one value from the request: the body, with an XPath or JSONPath expression, or a query parameter, a header or a REST path parameter by name. It then checks that the value equals a string, matches a regular expression, is present or is absent.
Each response sets its Status, a Delay (ms), its Headers and its Body (XML, JSON, text or none). The body is sent exactly as written, unless the response echoes request values (below). It never reads a property, a secret or the environment.
Echoing request values
Section titled “Echoing request values”A response can put values from the request into its body and header values. Declare each value under
values in the response file, reading it the way a match condition does, and write {{name}} where it
goes:
id: 01J9…name: Acceptedbody: jsonheaders: - name: X-Correlation-Id value: '{{correlation}}'values: orderId: { from: body, language: jsonpath, expression: $.order.id } correlation: { from: header, name: X-Correlation-Id }{ "id": "{{orderId}}", "state": "accepted" }- A value can come from the body (
xpathorjsonpath), aqueryparameter, aheaderor a RESTpathparameter. Nothing else: a template never reads a property, a secret or the environment. - A value the request does not carry is inserted as empty text.
- Each value is escaped once for where it lands: XML entities in an XML body, string escaping in a JSON
body. In a JSON body a placeholder must sit inside a string (
"{{orderId}}"), so a request can never add a field. A text body gets the value as it is. - A value is inserted once and never read again, so a request that sends
{{orderId}}gets that text back. - A header value that would carry a line break or another character a header may not hold is not sent:
the request gets a 500 (
mock-template-refused) and the log says why. - A
{{name}}that names no declared value is refused when the project loads. A response withoutvaluesis never a template, so{{in it is plain text.
A mock with a templated response is saved as version: 2. Wirebench 5.0.0 leaves such a mock alone
rather than load it without its values. A mock without one stays at version: 1. Editing values in the
app is not available yet: edit the response file, and the app keeps the values on every other edit.
Scenarios
Section titled “Scenarios”A scenario makes a mock remember. Give responses a Scenario name; a response marked Only in
state is a candidate only while its scenario is in that state, and Then move to changes the state
once it is sent. Every scenario starts in Started. For example, a GET /cart answers empty until
a POST /cart response moves the cart scenario to filled.
Reset state puts every scenario back to Started, and the turn of In order back to the first
response. Stopping a mock does the same.
A dispatch script
Section titled “A dispatch script”With By script, the operation’s dispatch.ts chooses. It sees the request and the scenario states,
and calls respond with the name of one of the responses:
if (request.query.express?.[0] === 'true') { respond('Next day');} else if (scenarios.get('stock') === 'empty') { respond('Out of stock');} else { respond('Default');}| Name | What it is |
|---|---|
request |
operation, method, path, query (each name’s values), headers (name and value pairs), pathParams and body as text |
responses |
The responses the script may pick, with their id and name |
respond(name) |
Picks a response. Without a call, the default response is sent |
scenarios |
get(name) and set(name, state) |
log(...) |
Writes to the mock’s log |
The script runs in the same sandbox as request scripts, with a second to finish. It has no properties, secrets, network or files. Choose Apply script to save it.
The editor checks the script as you type, with completion and hover for the names above. A misspelt
name, a request field that does not exist, or a respond with a name that is not one of the
operation’s responses shows as an error under the editor. The
script API reference lists the
declarations it is checked against.
Stubs against the contract
Section titled “Stubs against the contract”A mock checks the requests it receives, and the tab also checks the responses it would send. Under Stubs against the contract it lists each response whose status, headers or body the contract does not allow, so a stub that drifted from the contract shows up before a client test passes against the mock and fails against the real service. The check runs when the tab opens and after every edit, and the same findings appear in the Problems view. Select a finding to show its operation.
Each response gets the checks a received response gets:
- SOAP: the envelope structure, the
Content-Typeagainst the binding’s SOAP version, and the body against the operation’s output message. A fault gets the structure checks only. A reply is sent with 200, a fault with 500 (400 or 500 in SOAP 1.2), and a one-way operation’s empty acknowledgement with 200 or 202. - REST: the status must be one the operation documents (exactly, by range such as
4XX, or asdefault), theContent-Typeone it declares for that status, and a JSON body must match the media type’s schema.
A response of an operation the contract no longer has is not checked; starting the mock warns of it.
In a pipeline, wirebench mock check runs the same check and fails when a stub does not conform (see
Run in CI).
The request log
Section titled “The request log”The tab lists every request the mock answered this session: the time, the method and path, the
operation and response, the status and how long it took. Select a row to see the request and the
response, with the problems the contract check found. Credentials a client sent (Authorization,
Cookie and the like) are masked. Clear empties the list.
Who can reach a mock
Section titled “Who can reach a mock”A mock listens on this machine only (127.0.0.1), and refuses a request whose Host names anything
else, so a web page can’t reach it by renaming itself. To serve a phone or another machine, turn on
Preferences → Mock services → Listen on all interfaces.
A mock stops when you stop it, close its project or quit Wirebench. It is never started for you.
Where it is saved
Section titled “Where it is saved”mocks/ orders-mock/ mock.yaml operations/ place-order/ operation.yaml accepted.response.yaml accepted.body.xml dispatch.tsEach response is a file with its body beside it, so two people adding responses edit different files, and a body diffs as XML or JSON. The project format describes every field.