An expectation can also run extra webhooks or callbacks before or after its response — see Before & After Actions for mirroring, fan-out, shadow, and gating patterns.

Please Note: There are over 100 more detailed code examples in Java, JavaScript, Python, Ruby, Go, .NET, Rust, PHP and the REST API below.

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withMethod("POST")
            .withPath("/login")
            .withBody("{username: 'foo', password: 'bar'}")
    )
    .respond(
        response()
            .withStatusCode(302)
            .withCookie(
                "sessionId", "2By8LOhBmaW5nZXJwcmludCIlMDAzMW"
            )
            .withHeader(
                "Location", "https://www.mock-server.com"
            )
    );

Please Note: There are over 100 more detailed code examples in Java, JavaScript, Python, Ruby, Go, .NET, Rust, PHP and the REST API below.

var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "method": "POST",
        "path": "/login",
        "body": {
            "username": "foo",
            "password": "bar"
        }
    },
    "httpResponse": {
        "statusCode": 302,
        "headers": {
            "Location": [
                "https://www.mock-server.com"
            ]
        },
        "cookies": {
            "sessionId": "2By8LOhBmaW5nZXJwcmludCIlMDAzMW"
        }
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);
from mockserver import MockServerClient, HttpRequest, HttpResponse

client = MockServerClient("localhost", 1080)
client.when(
    HttpRequest(
        method="POST",
        path="/login",
        body="{username: 'foo', password: 'bar'}"
    )
).respond(
    HttpResponse(
        status_code=302,
        headers={"Location": ["https://www.mock-server.com"]}
    )
)
require 'mockserver-client'
include MockServer

client = MockServer::Client.new('localhost', 1080)
client.when(
  HttpRequest.new(
    method: 'POST',
    path: '/login',
    body: "{username: 'foo', password: 'bar'}"
  )
).respond(
  HttpResponse.new(
    status_code: 302,
    headers: { 'Location' => ['https://www.mock-server.com'] }
  )
)
import mockserver "github.com/mock-server/mockserver-monorepo/mockserver-client-go"

client := mockserver.New("localhost", 1080)
client.When(
    mockserver.Request().
        Method("POST").
        Path("/login").
        Body("{username: 'foo', password: 'bar'}"),
).Respond(
    mockserver.Response().
        StatusCode(302).
        Header("Location", "https://www.mock-server.com"),
)
using MockServer.Client;
using MockServer.Client.Models;

using var client = new MockServerClient("localhost", 1080);
client.When(
    HttpRequest.Request()
        .WithMethod("POST")
        .WithPath("/login")
        .WithBody("{username: 'foo', password: 'bar'}")
).Respond(
    HttpResponse.Response()
        .WithStatusCode(302)
        .WithHeader("Location", "https://www.mock-server.com")
);
use mockserver_client::{ClientBuilder, HttpRequest, HttpResponse};

let client = ClientBuilder::new("localhost", 1080).build().unwrap();
client.when(
    HttpRequest::new()
        .method("POST")
        .path("/login")
        .body("{username: 'foo', password: 'bar'}"),
).respond(
    HttpResponse::new()
        .status_code(302)
        .header("Location", "https://www.mock-server.com"),
).unwrap();
use MockServer\MockServerClient;
use MockServer\HttpRequest;
use MockServer\HttpResponse;

$client = new MockServerClient('localhost', 1080);
$client->when(
    HttpRequest::request()
        ->method('POST')
        ->path('/login')
        ->body("{username: 'foo', password: 'bar'}")
)->respond(
    HttpResponse::response()
        ->statusCode(302)
        ->header('Location', 'https://www.mock-server.com')
);

To use the Java client add the org.mock-server:mockserver-client-java-no-dependencies:7.2.0 dependency. The -no-dependencies artifact bundles all dependencies with relocated packages, so it declares zero transitive dependencies — this avoids classpath conflicts and CVE scanning noise from unused transitive dependencies.

For more details about the different dependency versions see the page on Maven Central

for example in maven:

<dependency>
	<groupId>org.mock-server</groupId>
	<artifactId>mockserver-client-java-no-dependencies</artifactId>
	<version>7.2.0</version>
</dependency>

A request matcher expectation may contain:

  • request matcher - used to match which requests this expectation should be applied to
  • action - what action to take, actions include response, forward, forward with fallback, callback and error
  • times (optional) - how many times the action should be taken
  • timeToLive (optional) - how long the expectation should stay active
  • priority (optional) - matching is ordered by priority (highest first) then creation (earliest first)
  • id (optional) - used for updating an existing expectation (i.e. when the id matches)
  • scenario (optional) - used for stateful multi-step API flows where the response changes based on prior interactions
  • httpResponses (optional) - an array of responses to cycle through sequentially or randomly on each match

open api expectations are also supported using an OpenAPI v3 specifications to generate request matcher expectations for each operation, see the section on open api expectations for details.

 

Matching Order

MockServer will match (or play) active expectations in the exact order they are added (if their priority is identical). For example, if an expectation A is added with Times.exactly(3) then expectation B is added with Times.exactly(2) with the same request matcher they will be applied in the following order A, A, A, B, B. Priority can be used to alter the order that expectations are matched; matching is ordered by priority (highest first) then creation (earliest first).

Priority can be used to configure a default expectation or response by specifying a negative value for priority and a very lax request matcher; the lax request matcher ensures the default expectation is always matched, but the low priority ensure it is matched last after all other expectations.

 

Probabilistic Matching (Percentage)

An expectation can be configured with a percentage (0-100) to enable probabilistic matching. When set, the expectation will only match the specified percentage of requests that structurally match the request matcher. This is useful for simulating intermittent failures, flaky services, or A/B testing scenarios.

For example, setting percentage to 50 means approximately half of matching requests will be handled by this expectation, while the other half will fall through to the next matching expectation or the default behavior.

If percentage is not set or set to 100, the expectation matches all structurally matching requests (the default behavior). A value of 0 means the expectation never matches.

 

Stateful Scenarios

MockServer can model multi-step, stateful API behaviour — where the response to a request depends on what happened before. This covers named state-machine scenarios (using scenarioName / scenarioState / newScenarioState), sequential / cycling responses (httpResponses + responseMode), timed and externally-triggered state transitions, and cross-protocol scenario correlation.

These features have their own page with a feature overview and runnable examples for every client — Java, JavaScript, Python, Ruby, Go, .NET, Rust, PHP, the REST API and JSON:

→ Stateful Scenarios

 

Updating Expectations

If an expectation is added and the id field matches an existing expectation the existing expectation will be updated (i.e. replaced). A UUID will be used assigned to each expectation if no value for id is specified.

 

Request Matchers

There are two types of request matcher:

 

A request properties matcher matches requests using one or more of the following properties:

 

Matching for properties can be done using:

  • string value
  • regex value
  • json schema
  • optional value
    • use for: method, path, path parameters values, query parameter keys, query parameters values, header keys, header values, cookie keys, cookie values or bodies
    • not supported for: path parameter keys
    • examples: query parameters, headers, cookies
  • negated value
    • use for: method, path, path parameter keys, path parameters values, query parameter keys, query parameters values, header keys, header values, cookie keys, cookie values or bodies
    • examples: method, path, headers
 

Note: path values containing { or } characters (such as /api/{id}) are interpreted as regex patterns, not literal strings. This is a common source of unexpected matching behaviour when path templates are used. To match literal curly braces in a path, use one of the following approaches:

  • Use an explicit regex matcher and escape the braces: withPath(regex("/api/\\{id\\}"))
  • Use an exact string matcher: withPath(exact("/api/{id}"))
 

Matching for key to multiple values supports multiple values for each key for headers, query parameters and path parameters

  • Keys support all property matcher except json schema
  • Values support all property matcher except optional values
  • Matching supports two modes:
    • sub set (default) - matches if the request property contains a matching sub set (considering optional keys), therefore there is at least one matching value for each non-optional key or optional key if present
    • matching key - matches if the request property contains only matching values (considering optional keys), therefore all values must match for each non-optional key or optional key if present

Note: for query parameters, the default sub set matching mode means that extra query parameters not specified in the matcher are allowed and do not cause a match failure. To enforce strict matching where only the specified query parameters are allowed (and any additional parameters cause a mismatch), use KeyMatchStyle.MATCHING_KEY on the request matcher. For example:

request()
    .withPath("/some/path")
    .withQueryStringParameters(
        new Parameters(
            param("key", "value")
        ).withKeyMatchStyle(KeyMatchStyle.MATCHING_KEY)
    )
 

Matching for key to single value supports a single value for each key for cookies

   

Important: when matching JSON bodies, there is a significant difference between plain string matching and semantic JSON matching:

  • withBody("{\"key\": \"value\"}") performs a character-by-character string comparison. This means whitespace, key ordering, and formatting must match exactly. For example, {"key":"value"} would not match {"key": "value"} because of the missing space.
  • withBody(json("{\"key\": \"value\"}")) performs a semantic JSON comparison. This ignores whitespace and (with ONLY_MATCHING_FIELDS) allows additional fields. Use this for matching JSON payloads.

If your expectations are not matching JSON requests as expected, ensure you are using json() rather than passing the JSON string directly.

Matching for bodies can be done using:

  • plain text (i.e. exact match)
  • regular expression - see Java regex syntax
  • JSON - supports:
    • matchType to control which fields get matched:
      • STRICT matches all fields, order of arrays and no additional fields allowed
      • ONLY_MATCHING_FIELDS only matches fields provided in the request matcher
    • matchNumbersAsStrings (optional, default false) if true, numeric values are compared by numeric value regardless of type, so 1, 1.0 and 1.00 are all considered equal. This is useful when different languages or serializers produce different numeric representations for the same value (e.g. Java sends 1.0 while Groovy sends 1).
    • JSONUnit placeholders to allow fields or values to be ignored or matched by type or pattern, for example:
      • ${json-unit.ignore-element} ignore a field
      • ${json-unit.any-boolean} match a field as any boolean
      • ${json-unit.any-string} match a field as any string
      • ${json-unit.any-number} match a field as any number
      • ${json-unit.regex}pattern match a field by regex, e.g. ${json-unit.regex}[a-z]+
      • ${json-unit.matches:name} match a field with a user-registered custom matcher (e.g. ${json-unit.matches:largerThan}); register the matcher by setting the mockserver.customJsonUnitMatchersClass configuration property to a class implementing CustomJsonUnitMatcherProvider
      see JSONUnit documentation for full details
  • JSON Schema - see JSON Schema documentation
  • JsonPath - matches if at least one value is returned by the expression, see JsonPath documentation
  • XML - supports:
    • XMLUnit placeholders to allow fields or elements to be ignored or matched by type for example:
      • ${xmlunit.ignore} ignore an element
      • ${xmlunit.isNumber} match an element or attribute as a number
      see XMLUnit documentation for full details
  • XML Schema - see XML Schema documentation
  • XPath - matches if at least one value returned by expression, see XPath specification
  • form fields (i.e. body parameters)
  • multipart/form-data — match file uploads and mixed field/file requests by field value, filename, or part content-type
  • binary
  • GraphQL - whitespace-insensitive matching of GraphQL queries, mutations, and subscriptions
  • fuzzy / similarity - deterministic Jaro-Winkler similarity match at or above a configurable threshold
  • negated matcher
 

GraphQL Body Matching

MockServer supports whitespace-insensitive matching of GraphQL over HTTP JSON request bodies. This allows expectations to match GraphQL queries, mutations, and subscriptions regardless of whitespace, formatting, or comment differences. The request body must be a JSON object with a query field (the standard GraphQL over HTTP format).

A GraphQL body matcher can specify:

  • query (required) - the GraphQL query string. Whitespace is normalized before comparison, so { user { name } } matches {\n user {\n name\n }\n}
  • operationName (optional) - match the operation name exactly, or using a regex pattern (e.g. Get.*)
  • variablesSchema (optional) - a JSON Schema to validate the variables field
  • selectionSetMatchType (optional) - controls how the selection set (fields) is compared. Values:
    • NORMALISED_STRING (default) - whitespace-normalised string comparison of the full query
    • AST_EXACT - matches operation type, name, and the exact set of top-level field names (ignores whitespace, nested fields, and argument differences)
    • AST_SUBSET - matches when the expected top-level fields are a subset of the actual request's fields (useful when the request may contain additional fields)
  • fields (optional) - explicit list of top-level field names to match in AST modes. If not specified, fields are extracted from the query string
  • schema (optional) - a GraphQL schema (SDL text or an introspection JSON result) used to synthesize a schema-valid response for the matched query without hand-authoring the response JSON

Example - match a GraphQL query:

{
    "httpRequest": {
        "method": "POST",
        "path": "/graphql",
        "body": {
            "type": "GRAPHQL",
            "query": "{ user(id: 1) { name email } }"
        }
    },
    "httpResponse": {
        "statusCode": 200,
        "body": "{\"data\": {\"user\": {\"name\": \"Alice\", \"email\": \"alice@example.com\"}}}"
    }
}

Example - match with operation name and variables schema:

{
    "httpRequest": {
        "method": "POST",
        "path": "/graphql",
        "body": {
            "type": "GRAPHQL",
            "query": "query GetUser($id: ID!) { user(id: $id) { name email } }",
            "operationName": "GetUser",
            "variablesSchema": "{\"type\": \"object\", \"properties\": {\"id\": {\"type\": \"string\"}}, \"required\": [\"id\"]}"
        }
    },
    "httpResponse": {
        "statusCode": 200,
        "body": "{\"data\": {\"user\": {\"name\": \"Alice\", \"email\": \"alice@example.com\"}}}"
    }
}

Example - match a mutation:

{
    "httpRequest": {
        "method": "POST",
        "path": "/graphql",
        "body": {
            "type": "GRAPHQL",
            "query": "mutation CreateUser($input: CreateUserInput!) { createUser(input: $input) { id name } }",
            "operationName": "CreateUser"
        }
    },
    "httpResponse": {
        "statusCode": 200,
        "body": "{\"data\": {\"createUser\": {\"id\": \"123\", \"name\": \"Alice\"}}}"
    }
}

Example - AST subset matching (match any query containing a "users" field):

{
    "httpRequest": {
        "method": "POST",
        "path": "/graphql",
        "body": {
            "type": "GRAPHQL",
            "query": "query { users { id } }",
            "selectionSetMatchType": "AST_SUBSET",
            "fields": ["users"]
        }
    },
    "httpResponse": {
        "statusCode": 200,
        "body": "{\"data\": {\"users\": [{\"id\": \"1\", \"name\": \"Alice\"}]}}"
    }
}

Example - AST exact matching (match a query with exactly these top-level fields):

{
    "httpRequest": {
        "method": "POST",
        "path": "/graphql",
        "body": {
            "type": "GRAPHQL",
            "query": "query GetDashboard { user profile settings }",
            "selectionSetMatchType": "AST_EXACT"
        }
    },
    "httpResponse": {
        "statusCode": 200,
        "body": "{\"data\": {\"user\": {}, \"profile\": {}, \"settings\": {}}}"
    }
}
 

GraphQL Schema-Based Response Synthesis

Instead of hand-authoring the response JSON for every GraphQL query, you can register a GraphQL schema on the expectation and let MockServer build a schema-valid response automatically. Provide the schema as either SDL text (e.g. type Query { hello: String }) or an introspection JSON result.

When a request matches an expectation whose GraphQL body carries a schema, MockServer reads the query's selection set and returns a {"data": {...}} response that respects the schema's types:

  • only the fields the client asked for appear in the response (selection-set subsets are honoured)
  • scalars get sensible deterministic placeholders — String, Int, Float, Boolean, ID, plus common custom scalars such as DateTime and JSON
  • enum fields return their first declared value
  • list fields return a single-element array; nested object fields recurse into their sub-selection
  • non-null wrappers are unwrapped; field aliases, __typename, inline fragments, and named fragment spreads are all supported

This is useful for quickly standing up a realistic GraphQL mock from an existing schema — no example payloads required. To return a specific, hand-crafted payload instead, simply provide an httpResponse body as in the matching examples above.

Example - synthesize a response from an SDL schema:

{
    "httpRequest": {
        "method": "POST",
        "path": "/graphql",
        "body": {
            "type": "GRAPHQL",
            "query": "{ user { name email } }",
            "schema": "type Query { user: User } type User { id: ID name: String email: String age: Int }"
        }
    }
}

A request with the query { user { name email } } yields a schema-valid response containing only the requested fields, for example:

{ "data": { "user": { "name": "string", "email": "string" } } }
 

GraphQL Subscriptions over WebSocket

MockServer supports mocking GraphQL subscriptions over WebSocket using the graphql-transport-ws protocol (also accepts the legacy graphql-ws subprotocol). This allows testing GraphQL subscription clients without a real GraphQL server.

The protocol flow is:

  1. Client opens a WebSocket connection with Sec-WebSocket-Protocol: graphql-transport-ws
  2. Client sends connection_init, MockServer replies connection_ack
  3. Client sends subscribe with a GraphQL query; MockServer AST-matches the query against the configured filter
  4. On match: MockServer pushes a sequence of next messages (with optional delays), then complete
  5. On no match: MockServer sends an error message
  6. Client can send complete to cancel a subscription
  7. ping/pong keepalive is supported

To configure a GraphQL subscription mock, use an httpWebSocketResponse with:

  • subprotocol - set to graphql-transport-ws (or graphql-ws)
  • graphqlSubscriptionFilter - a GraphQL body filter specifying the subscription query to match. Supports the same selectionSetMatchType options as GraphQL body matching
  • messages - the sequence of payloads to push as next events. Each message's text is wrapped in the protocol envelope {"id":"...","type":"next","payload":{"data":...}}

Example - mock a GraphQL subscription that pushes two events:

{
    "httpRequest": {
        "method": "GET",
        "path": "/graphql"
    },
    "httpWebSocketResponse": {
        "subprotocol": "graphql-transport-ws",
        "graphqlSubscriptionFilter": {
            "query": "subscription { userUpdated { id name } }",
            "selectionSetMatchType": "AST_SUBSET"
        },
        "messages": [
            {"text": "{\"id\": \"1\", \"name\": \"Alice\"}"},
            {"text": "{\"id\": \"2\", \"name\": \"Bob\"}", "delay": {"timeUnit": "MILLISECONDS", "value": 500}}
        ]
    }
}

Example - Java API:

mockServerClient.when(
    request()
        .withMethod("GET")
        .withPath("/graphql")
).respondWithWebSocket(
    webSocketResponse()
        .withSubprotocol("graphql-transport-ws")
        .withGraphqlSubscriptionFilter(
            GraphQLBody.graphQL("subscription { userUpdated { id name } }")
                .withSelectionSetMatchType(SelectionSetMatchType.AST_SUBSET)
        )
        .withMessage(webSocketMessage("{\"id\": \"1\", \"name\": \"Alice\"}"))
        .withMessage(webSocketMessage("{\"id\": \"2\", \"name\": \"Bob\"}"))
);

When a client connects and sends:

{"type": "connection_init"}
// MockServer replies: {"type": "connection_ack"}

{"id": "1", "type": "subscribe", "payload": {"query": "subscription { userUpdated { id name } }"}}
// MockServer replies:
// {"id": "1", "type": "next", "payload": {"data": {"id": "1", "name": "Alice"}}}
// {"id": "1", "type": "next", "payload": {"data": {"id": "2", "name": "Bob"}}}
// {"id": "1", "type": "complete"}

Note: The legacy graphql-ws subprotocol (used by the older subscriptions-transport-ws library) is also accepted. Both use the same message format in MockServer's implementation.

 

Fuzzy / Similarity Body Matching

The FUZZY body matcher matches when the request body is similar enough to an expected string, using a deterministic normalised Jaro-Winkler similarity ratio with a configurable threshold. Unlike LLM-based semantic matching, it is fully deterministic — the same inputs always produce the same result and it requires no external service.

JSON format:

{
    "httpRequest": {
        "method": "POST",
        "path": "/api/search",
        "body": {
            "type": "FUZZY",
            "fuzzy": "find orders for user",
            "threshold": 0.8,
            "ignoreCase": false
        }
    },
    "httpResponse": {
        "statusCode": 200,
        "body": "{\"results\": []}"
    }
}

Fields:

  • fuzzy — the expected string to compare against
  • threshold (optional, default 0.8) — required similarity ratio between 0.0 and 1.0. A value of 1.0 requires an exact match; 0.0 matches anything.
  • ignoreCase (optional, default false) — when true, both strings are trimmed and lower-cased before comparison

Java DSL:

import static org.mockserver.model.FuzzyBody.fuzzy;

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withMethod("POST")
            .withPath("/api/search")
            .withBody(fuzzy("find orders for user", 0.8, false))
    )
    .respond(
        response().withStatusCode(200).withBody("{\"results\": []}")
    );
 

Conditional (if/then/else) Request Matcher

A conditionalRequestDefinition lets you combine request matchers with if/then/else logic. If the if guard matches the incoming request, the then branch must also match; otherwise the else branch must match (when absent, the expectation matches whenever the guard is false). Each branch can be any request definition — an httpRequest, an OpenAPI definition, or even a nested conditionalRequestDefinition.

{
    "conditionalRequestDefinition": {
        "if": {
            "method": "POST",
            "headers": { "content-type": ["application/json"] }
        },
        "then": {
            "body": {
                "type": "JSON_SCHEMA",
                "jsonSchema": "{\"type\": \"object\", \"required\": [\"orderId\"]}"
            }
        },
        "else": {
            "method": "GET"
        }
    },
    "httpResponse": {
        "statusCode": 200
    }
}

This expectation matches either a JSON POST whose body contains an orderId field, or a GET request. Existing AND-only expectations are unchanged — this construct is entirely opt-in.

Java DSL:

import static org.mockserver.model.ConditionalRequestDefinition.requestIf;

new MockServerClient("localhost", 1080)
    .when(
        requestIf(
            request().withMethod("POST").withHeader("content-type", "application/json"),
            request().withBody(json("{\"orderId\": \"${json-unit.any-string}\"}")),
            request().withMethod("GET")
        )
    )
    .respond(response().withStatusCode(200));
 

Accept-Header Content-Negotiation Matching

A header matcher value may use an opt-in accept:<media-type> directive to match when the request's Accept header finds the media type acceptable per RFC 7231 §5.3.2. This honours q-weights (q=0 excludes a type), type/* and */* wildcards, and specificity/preference ordering.

Use this form as a header value matcher in the Accept header entry:

{
    "httpRequest": {
        "method": "GET",
        "path": "/api/resource",
        "headers": {
            "Accept": ["accept:application/json"]
        }
    },
    "httpResponse": {
        "statusCode": 200,
        "headers": { "Content-Type": ["application/json"] },
        "body": "{\"result\": \"json response\"}"
    }
}

This expectation matches requests whose Accept header finds application/json acceptable — for example Accept: application/json, Accept: */*, or Accept: application/json;q=0.9, text/html;q=0.5. A request sending Accept: text/html or Accept: application/json;q=0 would not match.

Existing exact/regex header matching is unchanged when the accept: prefix is absent.

The following code examples show how to match against different elements of a request using different matchers. For more examples see the code examples folder in the git repository.

For brevity static imports have not been included in the Java code examples so please add the following static imports if copying this code

import static org.mockserver.model.HttpRequest.request;
import static org.mockserver.model.HttpResponse.response;

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/some/path"),
        Times.once(),
        TimeToLive.exactly(TimeUnit.SECONDS, 60L),
        10
    )
    .respond(
        response()
            .withBody("some_response_body")
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "path": "/some/path"
    },
    "httpResponse": {
        "body": "some_response_body"
    },
    "times": {
        "remainingTimes": 1,
        "unlimited": false
    },
    "timeToLive": {
        "timeUnit": "SECONDS",
        "timeToLive": 60,
        "unlimited": false
    },
    "priority" : 10
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import HttpRequest, HttpResponse

client = MockServerClient("localhost", 1080)
client.when(
    HttpRequest.request("/some/path")
).respond(
    HttpResponse.response(body="some_response_body")
)
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.when(
    MockServer::HttpRequest.new(path: '/some/path')
).respond(
    MockServer::HttpResponse.new(body: 'some_response_body')
)
import mockserver "github.com/mock-server/mockserver-monorepo/mockserver-client-go"

client := mockserver.New("localhost", 1080)
client.When(
    mockserver.Request().Path("/some/path"),
).Respond(
    mockserver.Response().Body("some_response_body"),
)
using MockServer.Client;
using MockServer.Client.Models;

using var client = new MockServerClient("localhost", 1080);
client.When(
    HttpRequest.Request().WithPath("/some/path")
).Respond(
    HttpResponse.Response().WithBody("some_response_body")
);
use mockserver_client::{ClientBuilder, HttpRequest, HttpResponse};

let client = ClientBuilder::new("localhost", 1080).build().unwrap();
client.when(HttpRequest::new().path("/some/path"))
    .respond(HttpResponse::new().body("some_response_body"))
    .unwrap();
use MockServer\MockServerClient;
use MockServer\HttpRequest;
use MockServer\HttpResponse;
use MockServer\Times;

$client = new MockServerClient('localhost', 1080);
$client->when(
    HttpRequest::request()
        ->path('/some/path'), Times::exactly(1)
)->respond(
    HttpResponse::response()
        ->body('some_response_body')
);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
  "httpRequest" : {
    "path" : "/some/path"
  },
  "httpResponse" : {
    "body" : "some_response_body"
  },
  "times" : {
    "remainingTimes" : 1,
    "unlimited" : false
  },
  "timeToLive" : {
    "timeUnit" : "SECONDS",
    "timeToLive" : 60,
    "unlimited" : false
  },
  "priority" : 10
}'

See REST API for full JSON specification

A negative priority can be used to specify a default expectation or response.

new MockServerClient("localhost", 1080)
    .when(
        request(),
        Times.once(),
        TimeToLive.exactly(TimeUnit.SECONDS, 60L),
        -10
    )
    .respond(
        response()
            .withBody("some_default_response_body")
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {},
    "httpResponse": {
        "body": "some_default_response_body"
    },
    "times": {
        "remainingTimes": 1,
        "unlimited": false
    },
    "timeToLive": {
        "timeUnit": "SECONDS",
        "timeToLive": 60,
        "unlimited": false
    },
    "priority" : -10
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import HttpRequest, HttpResponse

client = MockServerClient("localhost", 1080)
client.when(
    HttpRequest.request()
).respond(
    HttpResponse.response(body="some_default_response_body")
)
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.when(
    MockServer::HttpRequest.new
).respond(
    MockServer::HttpResponse.new(body: 'some_default_response_body')
)
import mockserver "github.com/mock-server/mockserver-monorepo/mockserver-client-go"

client := mockserver.New("localhost", 1080)
client.When(
    mockserver.Request(),
).Respond(
    mockserver.Response().Body("some_default_response_body"),
)
using MockServer.Client;
using MockServer.Client.Models;

using var client = new MockServerClient("localhost", 1080);
client.When(
    HttpRequest.Request()
).Respond(
    HttpResponse.Response().WithBody("some_default_response_body")
);
use mockserver_client::{ClientBuilder, HttpRequest, HttpResponse};

let client = ClientBuilder::new("localhost", 1080).build().unwrap();
client.when(HttpRequest::new())
    .respond(HttpResponse::new().body("some_default_response_body"))
    .unwrap();
use MockServer\MockServerClient;
use MockServer\HttpRequest;
use MockServer\HttpResponse;
use MockServer\Times;

$client = new MockServerClient('localhost', 1080);
$client->when(
    HttpRequest::request(), Times::exactly(1)
)->respond(
    HttpResponse::response()
        ->body('some_default_response_body')
);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
  "httpRequest" : {},
  "httpResponse" : {
    "body" : "some_default_response_body"
  },
  "times" : {
    "remainingTimes" : 1,
    "unlimited" : false
  },
  "timeToLive" : {
    "timeUnit" : "SECONDS",
    "timeToLive" : 60,
    "unlimited" : false
  },
  "priority" : -10
}'

See REST API for full JSON specification

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/some/path")
    )
    .respond(
        response()
            .withBody("some_response_body")
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "path": "/some/path"
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import HttpRequest, HttpResponse

client = MockServerClient("localhost", 1080)
client.when(
    HttpRequest.request("/some/path")
).respond(
    HttpResponse.response(body="some_response_body")
)
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.when(
    MockServer::HttpRequest.new(path: '/some/path')
).respond(
    MockServer::HttpResponse.new(body: 'some_response_body')
)
import mockserver "github.com/mock-server/mockserver-monorepo/mockserver-client-go"

client := mockserver.New("localhost", 1080)
client.When(
    mockserver.Request().Path("/some/path"),
).Respond(
    mockserver.Response().Body("some_response_body"),
)
using MockServer.Client;
using MockServer.Client.Models;

using var client = new MockServerClient("localhost", 1080);
client.When(
    HttpRequest.Request().WithPath("/some/path")
).Respond(
    HttpResponse.Response().WithBody("some_response_body")
);
use mockserver_client::{ClientBuilder, HttpRequest, HttpResponse};

let client = ClientBuilder::new("localhost", 1080).build().unwrap();
client.when(HttpRequest::new().path("/some/path"))
    .respond(HttpResponse::new().body("some_response_body"))
    .unwrap();
use MockServer\MockServerClient;
use MockServer\HttpRequest;
use MockServer\HttpResponse;

$client = new MockServerClient('localhost', 1080);
$client->when(
    HttpRequest::request()
        ->path('/some/path')
)->respond(
    HttpResponse::response()
        ->body('some_response_body')
);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
  "httpRequest" : {
    "path" : "/some/path"
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}'

See REST API for full JSON specification

Match (and verify) on the protocol a request actually arrived over. Supported values are HTTP_1_1, HTTP_2 and HTTP_3 (HTTP/3 is experimental). The protocol is determined by MockServer from the negotiated connection (ALPN for HTTP/2 and HTTP/3), so it cannot be spoofed by a request header. The protocol is optional: an expectation that does not specify a protocol matches a request regardless of which protocol it arrived over.

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/some/path")
            .withProtocol(Protocol.HTTP_2)
    )
    .respond(
        response()
            .withBody("some_response_body")
    );
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
  "httpRequest" : {
    "path" : "/some/path",
    "protocol" : "HTTP_2"
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}'

See REST API for full JSON specification

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/some/path"),
        Times.exactly(2)
    )
    .respond(
        response()
            .withBody("some_response_body")
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "path": "/some/path"
    },
    "httpResponse": {
        "body": "some_response_body"
    },
    "times": {
        "remainingTimes": 2
    },
    "timeToLive": {
        "unlimited": true
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import HttpRequest, HttpResponse

client = MockServerClient("localhost", 1080)
client.when(
    HttpRequest.request("/some/path")
).respond(
    HttpResponse.response(body="some_response_body")
)
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.when(
    MockServer::HttpRequest.new(path: '/some/path')
).respond(
    MockServer::HttpResponse.new(body: 'some_response_body')
)
import mockserver "github.com/mock-server/mockserver-monorepo/mockserver-client-go"

client := mockserver.New("localhost", 1080)
client.When(
    mockserver.Request().Path("/some/path"),
).Respond(
    mockserver.Response().Body("some_response_body"),
)
using MockServer.Client;
using MockServer.Client.Models;

using var client = new MockServerClient("localhost", 1080);
client.When(
    HttpRequest.Request().WithPath("/some/path")
).Respond(
    HttpResponse.Response().WithBody("some_response_body")
);
use mockserver_client::{ClientBuilder, HttpRequest, HttpResponse};

let client = ClientBuilder::new("localhost", 1080).build().unwrap();
client.when(HttpRequest::new().path("/some/path"))
    .respond(HttpResponse::new().body("some_response_body"))
    .unwrap();
use MockServer\MockServerClient;
use MockServer\HttpRequest;
use MockServer\HttpResponse;
use MockServer\Times;

$client = new MockServerClient('localhost', 1080);
$client->when(
    HttpRequest::request()
        ->path('/some/path'), Times::exactly(2)
)->respond(
    HttpResponse::response()
        ->body('some_response_body')
);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
  "httpRequest" : {
    "path" : "/some/path"
  },
  "httpResponse" : {
    "body" : "some_response_body"
  },
  "times" : {
    "remainingTimes" : 2,
    "unlimited" : false
  },
  "timeToLive" : {
    "unlimited" : true
  }
}'

See REST API for full JSON specification

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/some/path"),
        Times.once(),
        TimeToLive.exactly(TimeUnit.SECONDS, 60L)
    )
    .respond(
        response()
            .withBody("some_response_body")
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "path": "/some/path"
    },
    "httpResponse": {
        "body": "some_response_body"
    },
    "times": {
        "remainingTimes": 1,
        "unlimited": false
    },
    "timeToLive": {
        "timeUnit": "SECONDS",
        "timeToLive": 60,
        "unlimited": false
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import HttpRequest, HttpResponse

client = MockServerClient("localhost", 1080)
client.when(
    HttpRequest.request("/some/path")
).respond(
    HttpResponse.response(body="some_response_body")
)
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.when(
    MockServer::HttpRequest.new(path: '/some/path')
).respond(
    MockServer::HttpResponse.new(body: 'some_response_body')
)
import mockserver "github.com/mock-server/mockserver-monorepo/mockserver-client-go"

client := mockserver.New("localhost", 1080)
client.When(
    mockserver.Request().Path("/some/path"),
).Respond(
    mockserver.Response().Body("some_response_body"),
)
using MockServer.Client;
using MockServer.Client.Models;

using var client = new MockServerClient("localhost", 1080);
client.When(
    HttpRequest.Request().WithPath("/some/path")
).Respond(
    HttpResponse.Response().WithBody("some_response_body")
);
use mockserver_client::{ClientBuilder, HttpRequest, HttpResponse};

let client = ClientBuilder::new("localhost", 1080).build().unwrap();
client.when(HttpRequest::new().path("/some/path"))
    .respond(HttpResponse::new().body("some_response_body"))
    .unwrap();
use MockServer\MockServerClient;
use MockServer\HttpRequest;
use MockServer\HttpResponse;
use MockServer\Times;

$client = new MockServerClient('localhost', 1080);
$client->when(
    HttpRequest::request()
        ->path('/some/path'), Times::exactly(1)
)->respond(
    HttpResponse::response()
        ->body('some_response_body')
);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
  "httpRequest" : {
    "path" : "/some/path"
  },
  "httpResponse" : {
    "body" : "some_response_body"
  },
  "times" : {
    "remainingTimes" : 1,
    "unlimited" : false
  },
  "timeToLive" : {
    "timeUnit" : "SECONDS",
    "timeToLive" : 60,
    "unlimited" : false
  }
}'

See REST API for full JSON specification

For details of the full regex syntax supported please see the JDK documentation.

new MockServerClient("localhost", 1080)
    .when(
        request()
            // matches any requests those path starts with "/some"
            .withPath("/some.*")
    )
    .respond(
        response()
            .withBody("some_response_body")
    );
var mockServerClient = require('mockserver-client').mockServerClient;
// matches any requests those path starts with "/some"
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "path": "/some.*"
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import HttpRequest, HttpResponse

client = MockServerClient("localhost", 1080)
client.when(
    HttpRequest.request("/some.*")
).respond(
    HttpResponse.response(body="some_response_body")
)
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.when(
    MockServer::HttpRequest.new(path: '/some.*')
).respond(
    MockServer::HttpResponse.new(body: 'some_response_body')
)
import mockserver "github.com/mock-server/mockserver-monorepo/mockserver-client-go"

client := mockserver.New("localhost", 1080)
client.When(
    mockserver.Request().Path("/some.*"),
).Respond(
    mockserver.Response().Body("some_response_body"),
)
using MockServer.Client;
using MockServer.Client.Models;

using var client = new MockServerClient("localhost", 1080);
client.When(
    HttpRequest.Request().WithPath("/some.*")
).Respond(
    HttpResponse.Response().WithBody("some_response_body")
);
use mockserver_client::{ClientBuilder, HttpRequest, HttpResponse};

let client = ClientBuilder::new("localhost", 1080).build().unwrap();
client.when(HttpRequest::new().path("/some.*"))
    .respond(HttpResponse::new().body("some_response_body"))
    .unwrap();
use MockServer\MockServerClient;
use MockServer\HttpRequest;
use MockServer\HttpResponse;

$client = new MockServerClient('localhost', 1080);
$client->when(
    HttpRequest::request()
        ->path('/some.*')
)->respond(
    HttpResponse::response()
        ->body('some_response_body')
);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
  "httpRequest" : {
    "path" : "/some.*"
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}'

See REST API for full JSON specification

new MockServerClient("localhost", 1080)
    .when(
        request()
            // matches any requests those path does NOT start with "/some"
            .withPath(not("/some.*"))
    )
    .respond(
        response()
            .withBody("some_response_body")
    );
var mockServerClient = require('mockserver-client').mockServerClient;
// matches any requests those path does NOT start with "/some"
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "path": "!/some.*"
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import HttpRequest, HttpResponse

client = MockServerClient("localhost", 1080)
client.when(
    HttpRequest.request("!/some.*")
).respond(
    HttpResponse.response(body="some_response_body")
)
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.when(
    MockServer::HttpRequest.new(path: '!/some.*')
).respond(
    MockServer::HttpResponse.new(body: 'some_response_body')
)
import mockserver "github.com/mock-server/mockserver-monorepo/mockserver-client-go"

client := mockserver.New("localhost", 1080)
client.When(
    mockserver.Request().Path("!/some.*"),
).Respond(
    mockserver.Response().Body("some_response_body"),
)
using MockServer.Client;
using MockServer.Client.Models;

using var client = new MockServerClient("localhost", 1080);
client.When(
    HttpRequest.Request().WithPath("!/some.*")
).Respond(
    HttpResponse.Response().WithBody("some_response_body")
);
use mockserver_client::{ClientBuilder, HttpRequest, HttpResponse};

let client = ClientBuilder::new("localhost", 1080).build().unwrap();
client.when(HttpRequest::new().path("!/some.*"))
    .respond(HttpResponse::new().body("some_response_body"))
    .unwrap();
use MockServer\MockServerClient;
use MockServer\HttpRequest;
use MockServer\HttpResponse;

$client = new MockServerClient('localhost', 1080);
$client->when(
    HttpRequest::request()
        ->path('!/some.*')
)->respond(
    HttpResponse::response()
        ->body('some_response_body')
);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
  "httpRequest" : {
    "path" : "!/some.*"
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}'

See REST API for full JSON specification

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/some/path")
            .withPathParameters(
                param("cartId", "055CA455-1DF7-45BB-8535-4F83E7266092")
            )
            .withQueryStringParameters(
                param("type", "[A-Z0-9\\-]+")
            )
    )
    .respond(
        response()
            .withBody("some_response_body")
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
    "path": "/some/path/{cartId}",
        "pathParameters": {
            "cartId": ["055CA455-1DF7-45BB-8535-4F83E7266092"]
        },
        "queryStringParameters": {
            "type": ["[A-Z0-9\\-]+"]
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import Expectation

client = MockServerClient("localhost", 1080)
client.upsert(Expectation.from_dict({
    "httpRequest": {
    "path": "/some/path/{cartId}",
        "pathParameters": {
            "cartId": ["055CA455-1DF7-45BB-8535-4F83E7266092"]
        },
        "queryStringParameters": {
            "type": ["[A-Z0-9\\-]+"]
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}))
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.upsert(MockServer::Expectation.from_hash({
    "httpRequest": {
    "path": "/some/path/{cartId}",
        "pathParameters": {
            "cartId": ["055CA455-1DF7-45BB-8535-4F83E7266092"]
        },
        "queryStringParameters": {
            "type": ["[A-Z0-9\\-]+"]
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}))
package main

import (
    "bytes"
    "net/http"
)

func main() {
    body := []byte(`{
    "httpRequest": {
    "path": "/some/path/{cartId}",
        "pathParameters": {
            "cartId": ["055CA455-1DF7-45BB-8535-4F83E7266092"]
        },
        "queryStringParameters": {
            "type": ["[A-Z0-9\\-]+"]
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}`)
    req, _ := http.NewRequest("PUT",
        "http://localhost:1080/mockserver/expectation",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    http.DefaultClient.Do(req)
}
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
    ""httpRequest"": {
    ""path"": ""/some/path/{cartId}"",
        ""pathParameters"": {
            ""cartId"": [""055CA455-1DF7-45BB-8535-4F83E7266092""]
        },
        ""queryStringParameters"": {
            ""type"": [""[A-Z0-9\\-]+""]
        }
    },
    ""httpResponse"": {
        ""body"": ""some_response_body""
    }
}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
    "httpRequest": {
    "path": "/some/path/{cartId}",
        "pathParameters": {
            "cartId": ["055CA455-1DF7-45BB-8535-4F83E7266092"]
        },
        "queryStringParameters": {
            "type": ["[A-Z0-9\\-]+"]
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
$json = <<<'JSON'
{
    "httpRequest": {
    "path": "/some/path/{cartId}",
        "pathParameters": {
            "cartId": ["055CA455-1DF7-45BB-8535-4F83E7266092"]
        },
        "queryStringParameters": {
            "type": ["[A-Z0-9\\-]+"]
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}
JSON;

$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_POSTFIELDS     => $json,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json; charset=utf-8'],
    CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
curl_close($ch);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest": {
    "path": "/some/path/{cartId}",
        "pathParameters": {
            "cartId": ["055CA455-1DF7-45BB-8535-4F83E7266092"]
        },
        "queryStringParameters": {
            "type": ["[A-Z0-9\\-]+"]
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}'

See REST API for full JSON specification

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/some/path/{cartId}")
            .withPathParameters(
                param("cartId", "[A-Z0-9\\-]+")
            )
    )
    .respond(
        response()
            .withBody("some_response_body")
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "path": "/some/path/{cartId}",
        "pathParameters": {
            "cartId": ["[A-Z0-9\\-]+"]
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import Expectation

client = MockServerClient("localhost", 1080)
client.upsert(Expectation.from_dict({
    "httpRequest": {
        "path": "/some/path/{cartId}",
        "pathParameters": {
            "cartId": ["[A-Z0-9\\-]+"]
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}))
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.upsert(MockServer::Expectation.from_hash({
    "httpRequest": {
        "path": "/some/path/{cartId}",
        "pathParameters": {
            "cartId": ["[A-Z0-9\\-]+"]
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}))
package main

import (
    "bytes"
    "net/http"
)

func main() {
    body := []byte(`{
    "httpRequest": {
        "path": "/some/path/{cartId}",
        "pathParameters": {
            "cartId": ["[A-Z0-9\\-]+"]
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}`)
    req, _ := http.NewRequest("PUT",
        "http://localhost:1080/mockserver/expectation",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    http.DefaultClient.Do(req)
}
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
    ""httpRequest"": {
        ""path"": ""/some/path/{cartId}"",
        ""pathParameters"": {
            ""cartId"": [""[A-Z0-9\\-]+""]
        }
    },
    ""httpResponse"": {
        ""body"": ""some_response_body""
    }
}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
    "httpRequest": {
        "path": "/some/path/{cartId}",
        "pathParameters": {
            "cartId": ["[A-Z0-9\\-]+"]
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
$json = <<<'JSON'
{
    "httpRequest": {
        "path": "/some/path/{cartId}",
        "pathParameters": {
            "cartId": ["[A-Z0-9\\-]+"]
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}
JSON;

$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_POSTFIELDS     => $json,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json; charset=utf-8'],
    CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
curl_close($ch);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest": {
        "path": "/some/path/{cartId}",
        "pathParameters": {
            "cartId": ["[A-Z0-9\\-]+"]
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}'

See REST API for full JSON specification

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/some/path/{cartId}/{maxItemCount}")
            .withPathParameters(
                schemaParam("cartId", "{\"type\": \"string\", \"pattern\": \"^[A-Z0-9\\-]+$\"}"),
                param(string("maxItemCount"), schemaString("{ \"type\": \"integer\" }"))
            )
    )
    .respond(
        response()
            .withBody("some_response_body")
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "path": "/some/path/{cartId}/{maxItemCount}",
        "pathParameters": {
            "cartId": [{
                "schema": {
                    "type": "string",
                    "pattern": "^[A-Z0-9-]+$"
                }
            }],
            "maxItemCount": [{
                "schema": {
                    "type": "integer"
                }
            }]
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import Expectation

client = MockServerClient("localhost", 1080)
client.upsert(Expectation.from_dict({
    "httpRequest": {
        "path": "/some/path/{cartId}/{maxItemCount}",
        "pathParameters": {
            "cartId": [{
                "schema": {
                    "type": "string",
                    "pattern": "^[A-Z0-9-]+$"
                }
            }],
            "maxItemCount": [{
                "schema": {
                    "type": "integer"
                }
            }]
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}))
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.upsert(MockServer::Expectation.from_hash({
    "httpRequest": {
        "path": "/some/path/{cartId}/{maxItemCount}",
        "pathParameters": {
            "cartId": [{
                "schema": {
                    "type": "string",
                    "pattern": "^[A-Z0-9-]+$"
                }
            }],
            "maxItemCount": [{
                "schema": {
                    "type": "integer"
                }
            }]
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}))
package main

import (
    "bytes"
    "net/http"
)

func main() {
    body := []byte(`{
    "httpRequest": {
        "path": "/some/path/{cartId}/{maxItemCount}",
        "pathParameters": {
            "cartId": [{
                "schema": {
                    "type": "string",
                    "pattern": "^[A-Z0-9-]+$"
                }
            }],
            "maxItemCount": [{
                "schema": {
                    "type": "integer"
                }
            }]
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}`)
    req, _ := http.NewRequest("PUT",
        "http://localhost:1080/mockserver/expectation",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    http.DefaultClient.Do(req)
}
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
    ""httpRequest"": {
        ""path"": ""/some/path/{cartId}/{maxItemCount}"",
        ""pathParameters"": {
            ""cartId"": [{
                ""schema"": {
                    ""type"": ""string"",
                    ""pattern"": ""^[A-Z0-9-]+$""
                }
            }],
            ""maxItemCount"": [{
                ""schema"": {
                    ""type"": ""integer""
                }
            }]
        }
    },
    ""httpResponse"": {
        ""body"": ""some_response_body""
    }
}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
    "httpRequest": {
        "path": "/some/path/{cartId}/{maxItemCount}",
        "pathParameters": {
            "cartId": [{
                "schema": {
                    "type": "string",
                    "pattern": "^[A-Z0-9-]+$"
                }
            }],
            "maxItemCount": [{
                "schema": {
                    "type": "integer"
                }
            }]
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
$json = <<<'JSON'
{
    "httpRequest": {
        "path": "/some/path/{cartId}/{maxItemCount}",
        "pathParameters": {
            "cartId": [{
                "schema": {
                    "type": "string",
                    "pattern": "^[A-Z0-9-]+$"
                }
            }],
            "maxItemCount": [{
                "schema": {
                    "type": "integer"
                }
            }]
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}
JSON;

$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_POSTFIELDS     => $json,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json; charset=utf-8'],
    CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
curl_close($ch);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest": {
        "path": "/some/path/{cartId}/{maxItemCount}",
        "pathParameters": {
            "cartId": [{
                "schema": {
                    "type": "string",
                    "pattern": "^[A-Z0-9-]+$"
                }
            }],
            "maxItemCount": [{
                "schema": {
                    "type": "integer"
                }
            }]
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}'

See REST API for full JSON specification

To match a path segment containing multiple values separated by delimiters (e.g. /2024-01-15/report), use a single path parameter with a regex value to match the entire compound segment.

new MockServerClient("localhost", 1080)
    .when(
        request()
            // matches paths like /2024-01-15/report or /val1-val2-val3/report
            .withPath("/{compound}/report")
            .withPathParameters(
                param("compound", "[^/]+-[^/]+-[^/]+")
            )
    )
    .respond(
        response()
            .withBody("some_response_body")
    );
var mockServerClient = require('mockserver-client').mockServerClient;
// matches paths like /2024-01-15/report or /val1-val2-val3/report
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "path": "/{compound}/report",
        "pathParameters": {
            "compound": ["[^/]+-[^/]+-[^/]+"]
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import Expectation

client = MockServerClient("localhost", 1080)
client.upsert(Expectation.from_dict({
    "httpRequest": {
        "path": "/{compound}/report",
        "pathParameters": {
            "compound": ["[^/]+-[^/]+-[^/]+"]
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}))
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.upsert(MockServer::Expectation.from_hash({
    "httpRequest": {
        "path": "/{compound}/report",
        "pathParameters": {
            "compound": ["[^/]+-[^/]+-[^/]+"]
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}))
package main

import (
    "bytes"
    "net/http"
)

func main() {
    body := []byte(`{
    "httpRequest": {
        "path": "/{compound}/report",
        "pathParameters": {
            "compound": ["[^/]+-[^/]+-[^/]+"]
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}`)
    req, _ := http.NewRequest("PUT",
        "http://localhost:1080/mockserver/expectation",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    http.DefaultClient.Do(req)
}
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
    ""httpRequest"": {
        ""path"": ""/{compound}/report"",
        ""pathParameters"": {
            ""compound"": [""[^/]+-[^/]+-[^/]+""]
        }
    },
    ""httpResponse"": {
        ""body"": ""some_response_body""
    }
}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
    "httpRequest": {
        "path": "/{compound}/report",
        "pathParameters": {
            "compound": ["[^/]+-[^/]+-[^/]+"]
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
$json = <<<'JSON'
{
    "httpRequest": {
        "path": "/{compound}/report",
        "pathParameters": {
            "compound": ["[^/]+-[^/]+-[^/]+"]
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}
JSON;

$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_POSTFIELDS     => $json,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json; charset=utf-8'],
    CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
curl_close($ch);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest": {
        "path": "/{compound}/report",
        "pathParameters": {
            "compound": ["[^/]+-[^/]+-[^/]+"]
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}'

See REST API for full JSON specification

For details of the full regex syntax supported please see the JDK documentation.

new MockServerClient("localhost", 1080)
    .when(
        request()
            // matches any requests that does NOT have a "GET" method
            .withMethod(not("P.*{2,3}"))
    )
    .respond(
        response()
            .withBody("some_response_body")
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "method": "P.*{2,3}"
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import HttpRequest, HttpResponse

client = MockServerClient("localhost", 1080)
client.when(
    HttpRequest.request()
        .with_method("P.*{2,3}")
).respond(
    HttpResponse.response(body="some_response_body")
)
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.when(
    MockServer::HttpRequest.new(method: 'P.*{2,3}')
).respond(
    MockServer::HttpResponse.new(body: 'some_response_body')
)
import mockserver "github.com/mock-server/mockserver-monorepo/mockserver-client-go"

client := mockserver.New("localhost", 1080)
client.When(
    mockserver.Request().Method("P.*{2,3}"),
).Respond(
    mockserver.Response().Body("some_response_body"),
)
using MockServer.Client;
using MockServer.Client.Models;

using var client = new MockServerClient("localhost", 1080);
client.When(
    HttpRequest.Request().WithMethod("P.*{2,3}")
).Respond(
    HttpResponse.Response().WithBody("some_response_body")
);
use mockserver_client::{ClientBuilder, HttpRequest, HttpResponse};

let client = ClientBuilder::new("localhost", 1080).build().unwrap();
client.when(HttpRequest::new().method("P.*{2,3}"))
    .respond(HttpResponse::new().body("some_response_body"))
    .unwrap();
use MockServer\MockServerClient;
use MockServer\HttpRequest;
use MockServer\HttpResponse;

$client = new MockServerClient('localhost', 1080);
$client->when(
    HttpRequest::request()
        ->method('P.*{2,3}')
)->respond(
    HttpResponse::response()
        ->body('some_response_body')
);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
  "httpRequest" : {
    "method" : "P.*{2,3}"
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}'

See REST API for full JSON specification

new MockServerClient("localhost", 1080)
    .when(
        request()
            // matches any requests that does NOT have a "GET" method
            .withMethod(not("GET"))
    )
    .respond(
        response()
            .withBody("some_response_body")
    );
var mockServerClient = require('mockserver-client').mockServerClient;
// matches any requests that does NOT have a "GET" method
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "method": "!GET"
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import HttpRequest, HttpResponse

client = MockServerClient("localhost", 1080)
client.when(
    HttpRequest.request()
        .with_method("!GET")
).respond(
    HttpResponse.response(body="some_response_body")
)
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.when(
    MockServer::HttpRequest.new(method: '!GET')
).respond(
    MockServer::HttpResponse.new(body: 'some_response_body')
)
import mockserver "github.com/mock-server/mockserver-monorepo/mockserver-client-go"

client := mockserver.New("localhost", 1080)
client.When(
    mockserver.Request().Method("!GET"),
).Respond(
    mockserver.Response().Body("some_response_body"),
)
using MockServer.Client;
using MockServer.Client.Models;

using var client = new MockServerClient("localhost", 1080);
client.When(
    HttpRequest.Request().WithMethod("!GET")
).Respond(
    HttpResponse.Response().WithBody("some_response_body")
);
use mockserver_client::{ClientBuilder, HttpRequest, HttpResponse};

let client = ClientBuilder::new("localhost", 1080).build().unwrap();
client.when(HttpRequest::new().method("!GET"))
    .respond(HttpResponse::new().body("some_response_body"))
    .unwrap();
use MockServer\MockServerClient;
use MockServer\HttpRequest;
use MockServer\HttpResponse;

$client = new MockServerClient('localhost', 1080);
$client->when(
    HttpRequest::request()
        ->method('!GET')
)->respond(
    HttpResponse::response()
        ->body('some_response_body')
);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
  "httpRequest" : {
    "method" : "!GET"
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}'

See REST API for full JSON specification

For details of the full regex syntax supported please see the JDK documentation.

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/some/path")
            .withQueryStringParameters(
                param("[A-z]{0,10}", "055CA455-1DF7-45BB-8535-4F83E7266092")
            )
    )
    .respond(
        response()
            .withBody("some_response_body")
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "path": "/some/path",
        "queryStringParameters": {
            "[A-z]{0,10}": ["055CA455-1DF7-45BB-8535-4F83E7266092"]
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import HttpRequest, HttpResponse

client = MockServerClient("localhost", 1080)
client.when(
    HttpRequest.request("/some/path")
        .with_query_param("[A-z]{0,10}", "055CA455-1DF7-45BB-8535-4F83E7266092")
).respond(
    HttpResponse.response(body="some_response_body")
)
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.when(
    MockServer::HttpRequest.new(path: '/some/path')
).respond(
    MockServer::HttpResponse.new(body: 'some_response_body')
)
import mockserver "github.com/mock-server/mockserver-monorepo/mockserver-client-go"

client := mockserver.New("localhost", 1080)
client.When(
    mockserver.Request().Path("/some/path").QueryStringParameter("[A-z]{0,10}", "055CA455-1DF7-45BB-8535-4F83E7266092"),
).Respond(
    mockserver.Response().Body("some_response_body"),
)
using MockServer.Client;
using MockServer.Client.Models;

using var client = new MockServerClient("localhost", 1080);
client.When(
    HttpRequest.Request().WithPath("/some/path").WithQueryStringParameter("[A-z]{0,10}", "055CA455-1DF7-45BB-8535-4F83E7266092")
).Respond(
    HttpResponse.Response().WithBody("some_response_body")
);
use mockserver_client::{ClientBuilder, HttpRequest, HttpResponse};

let client = ClientBuilder::new("localhost", 1080).build().unwrap();
client.when(HttpRequest::new().path("/some/path").query_param("[A-z]{0,10}", "055CA455-1DF7-45BB-8535-4F83E7266092"))
    .respond(HttpResponse::new().body("some_response_body"))
    .unwrap();
use MockServer\MockServerClient;
use MockServer\HttpRequest;
use MockServer\HttpResponse;

$client = new MockServerClient('localhost', 1080);
$client->when(
    HttpRequest::request()
        ->path('/some/path')
        ->queryStringParameter('[A-z]{0,10}', '055CA455-1DF7-45BB-8535-4F83E7266092')
)->respond(
    HttpResponse::response()
        ->body('some_response_body')
);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest": {
        "path": "/some/path",
        "queryStringParameters": {
            "[A-z]{0,10}": ["055CA455-1DF7-45BB-8535-4F83E7266092"]
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}'

See REST API for full JSON specification

For details of the full regex syntax supported please see the JDK documentation.

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/some/path")
            .withQueryStringParameters(
                param("cartId", "[A-Z0-9\\-]+")
            )
    )
    .respond(
        response()
            .withBody("some_response_body")
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "path": "/some/path",
        "queryStringParameters": {
            "cartId": ["[A-Z0-9\\-]+"]
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import HttpRequest, HttpResponse

client = MockServerClient("localhost", 1080)
client.when(
    HttpRequest.request("/some/path")
        .with_query_param("cartId", "[A-Z0-9\-]+")
).respond(
    HttpResponse.response(body="some_response_body")
)
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.when(
    MockServer::HttpRequest.new(path: '/some/path')
).respond(
    MockServer::HttpResponse.new(body: 'some_response_body')
)
import mockserver "github.com/mock-server/mockserver-monorepo/mockserver-client-go"

client := mockserver.New("localhost", 1080)
client.When(
    mockserver.Request().Path("/some/path").QueryStringParameter("cartId", "[A-Z0-9\-]+"),
).Respond(
    mockserver.Response().Body("some_response_body"),
)
using MockServer.Client;
using MockServer.Client.Models;

using var client = new MockServerClient("localhost", 1080);
client.When(
    HttpRequest.Request().WithPath("/some/path").WithQueryStringParameter("cartId", "[A-Z0-9\-]+")
).Respond(
    HttpResponse.Response().WithBody("some_response_body")
);
use mockserver_client::{ClientBuilder, HttpRequest, HttpResponse};

let client = ClientBuilder::new("localhost", 1080).build().unwrap();
client.when(HttpRequest::new().path("/some/path").query_param("cartId", "[A-Z0-9\-]+"))
    .respond(HttpResponse::new().body("some_response_body"))
    .unwrap();
use MockServer\MockServerClient;
use MockServer\HttpRequest;
use MockServer\HttpResponse;

$client = new MockServerClient('localhost', 1080);
$client->when(
    HttpRequest::request()
        ->path('/some/path')
        ->queryStringParameter('cartId', '[A-Z0-9\-]+')
)->respond(
    HttpResponse::response()
        ->body('some_response_body')
);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest": {
        "path": "/some/path",
        "queryStringParameters": {
            "cartId": ["[A-Z0-9\\-]+"]
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}'

See REST API for full JSON specification

This example shows the two ways a JSON Schema can be specified to match a query parameter value, either using the schemaParam static builder for parameters or the schemaString for static builder strings.

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/some/path")
            .withQueryStringParameters(
                schemaParam("cartId", "{\"type\": \"string\", \"pattern\": \"^[A-Z0-9\\-]+$\"}"),
                param(string("maxItemCount"), schemaString("{ \"type\": \"integer\" }"))
            )
    )
    .respond(
        response()
            .withBody("some_response_body")
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "path": "/some/path",
        "queryStringParameters": {
            "cartId": [{
                "schema": {
                    "type": "string",
                    "pattern": "^[A-Z0-9-]+$"
                }
            }],
            "maxItemCount": [{
                "schema": {
                    "type": "integer"
                }
            }]
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import Expectation

client = MockServerClient("localhost", 1080)
client.upsert(Expectation.from_dict({
    "httpRequest": {
        "path": "/some/path",
        "queryStringParameters": {
            "cartId": [{
                "schema": {
                    "type": "string",
                    "pattern": "^[A-Z0-9-]+$"
                }
            }],
            "maxItemCount": [{
                "schema": {
                    "type": "integer"
                }
            }]
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}))
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.upsert(MockServer::Expectation.from_hash({
    "httpRequest": {
        "path": "/some/path",
        "queryStringParameters": {
            "cartId": [{
                "schema": {
                    "type": "string",
                    "pattern": "^[A-Z0-9-]+$"
                }
            }],
            "maxItemCount": [{
                "schema": {
                    "type": "integer"
                }
            }]
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}))
package main

import (
    "bytes"
    "net/http"
)

func main() {
    body := []byte(`{
    "httpRequest": {
        "path": "/some/path",
        "queryStringParameters": {
            "cartId": [{
                "schema": {
                    "type": "string",
                    "pattern": "^[A-Z0-9-]+$"
                }
            }],
            "maxItemCount": [{
                "schema": {
                    "type": "integer"
                }
            }]
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}`)
    req, _ := http.NewRequest("PUT",
        "http://localhost:1080/mockserver/expectation",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    http.DefaultClient.Do(req)
}
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
    ""httpRequest"": {
        ""path"": ""/some/path"",
        ""queryStringParameters"": {
            ""cartId"": [{
                ""schema"": {
                    ""type"": ""string"",
                    ""pattern"": ""^[A-Z0-9-]+$""
                }
            }],
            ""maxItemCount"": [{
                ""schema"": {
                    ""type"": ""integer""
                }
            }]
        }
    },
    ""httpResponse"": {
        ""body"": ""some_response_body""
    }
}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
    "httpRequest": {
        "path": "/some/path",
        "queryStringParameters": {
            "cartId": [{
                "schema": {
                    "type": "string",
                    "pattern": "^[A-Z0-9-]+$"
                }
            }],
            "maxItemCount": [{
                "schema": {
                    "type": "integer"
                }
            }]
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
$json = <<<'JSON'
{
    "httpRequest": {
        "path": "/some/path",
        "queryStringParameters": {
            "cartId": [{
                "schema": {
                    "type": "string",
                    "pattern": "^[A-Z0-9-]+$"
                }
            }],
            "maxItemCount": [{
                "schema": {
                    "type": "integer"
                }
            }]
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}
JSON;

$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_POSTFIELDS     => $json,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json; charset=utf-8'],
    CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
curl_close($ch);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest": {
        "path": "/some/path",
        "queryStringParameters": {
            "cartId": [{
                "schema": {
                    "type": "string",
                    "pattern": "^[A-Z0-9-]+$"
                }
            }],
            "maxItemCount": [{
                "schema": {
                    "type": "integer"
                }
            }]
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}'

See REST API for full JSON specification

This example shows the two ways to specify an optional query parameter value, either using the optionalParam static builder for parameters or the optionalString for static builder strings.

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/some/path")
            .withQueryStringParameters(
                optionalParam("cartId", "[A-Z0-9\\-]+"),
                param(optionalString("maxItemCount"), schemaString("{ \"type\": \"integer\" }")),
                schemaParam(optionalString("userId"), "{ \"type\": \"string\", \"format\": \"uuid\" }")
            )
    )
    .respond(
        response()
            .withBody("some_response_body")
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "path": "/some/path",
        "queryStringParameters": {
            "?cartId": ["[A-Z0-9\\-]+"],
            "?maxItemCount": [{
                "schema": {
                    "type": "integer"
                }
            }],
            "?userId": [{
                "schema": {
                    "type": "string",
                    "format": "uuid"
                }
            }]
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import Expectation

client = MockServerClient("localhost", 1080)
client.upsert(Expectation.from_dict({
    "httpRequest": {
        "path": "/some/path",
        "queryStringParameters": {
            "?cartId": ["[A-Z0-9\\-]+"],
            "?maxItemCount": [{
                "schema": {
                    "type": "integer"
                }
            }],
            "?userId": [{
                "schema": {
                    "type": "string",
                    "format": "uuid"
                }
            }]
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}))
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.upsert(MockServer::Expectation.from_hash({
    "httpRequest": {
        "path": "/some/path",
        "queryStringParameters": {
            "?cartId": ["[A-Z0-9\\-]+"],
            "?maxItemCount": [{
                "schema": {
                    "type": "integer"
                }
            }],
            "?userId": [{
                "schema": {
                    "type": "string",
                    "format": "uuid"
                }
            }]
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}))
package main

import (
    "bytes"
    "net/http"
)

func main() {
    body := []byte(`{
    "httpRequest": {
        "path": "/some/path",
        "queryStringParameters": {
            "?cartId": ["[A-Z0-9\\-]+"],
            "?maxItemCount": [{
                "schema": {
                    "type": "integer"
                }
            }],
            "?userId": [{
                "schema": {
                    "type": "string",
                    "format": "uuid"
                }
            }]
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}`)
    req, _ := http.NewRequest("PUT",
        "http://localhost:1080/mockserver/expectation",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    http.DefaultClient.Do(req)
}
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
    ""httpRequest"": {
        ""path"": ""/some/path"",
        ""queryStringParameters"": {
            ""?cartId"": [""[A-Z0-9\\-]+""],
            ""?maxItemCount"": [{
                ""schema"": {
                    ""type"": ""integer""
                }
            }],
            ""?userId"": [{
                ""schema"": {
                    ""type"": ""string"",
                    ""format"": ""uuid""
                }
            }]
        }
    },
    ""httpResponse"": {
        ""body"": ""some_response_body""
    }
}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
    "httpRequest": {
        "path": "/some/path",
        "queryStringParameters": {
            "?cartId": ["[A-Z0-9\\-]+"],
            "?maxItemCount": [{
                "schema": {
                    "type": "integer"
                }
            }],
            "?userId": [{
                "schema": {
                    "type": "string",
                    "format": "uuid"
                }
            }]
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
$json = <<<'JSON'
{
    "httpRequest": {
        "path": "/some/path",
        "queryStringParameters": {
            "?cartId": ["[A-Z0-9\\-]+"],
            "?maxItemCount": [{
                "schema": {
                    "type": "integer"
                }
            }],
            "?userId": [{
                "schema": {
                    "type": "string",
                    "format": "uuid"
                }
            }]
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}
JSON;

$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_POSTFIELDS     => $json,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json; charset=utf-8'],
    CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
curl_close($ch);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest": {
        "path": "/some/path",
        "queryStringParameters": {
            "?cartId": ["[A-Z0-9\\-]+"],
            "?maxItemCount": [{
                "schema": {
                    "type": "integer"
                }
            }],
            "?userId": [{
                "schema": {
                    "type": "string",
                    "format": "uuid"
                }
            }]
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}'

See REST API for full JSON specification

Matching by keys to multiple-values by SUB_SET is the default mode this ensures at least one value with the same key matches, but MATCHING_KEY is also supported which ensures all values with the same key match.

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/some/path")
            .withQueryStringParameters(new Parameters(
                schemaParam("multiValuedParameter", "{\"type\": \"string\", \"pattern\": \"^[A-Z0-9\\-]+$\"}"),
                param(string("maxItemCount"), schemaString("{ \"type\": \"integer\" }"))
            ).withKeyMatchStyle(KeyMatchStyle.SUB_SET))
    )
    .respond(
        response()
            .withBody("some_response_body")
    );

Matching by SUB_SET is the default mode so nothing needs to be specified for this key match style.

var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest" : {
        "path" : "/some/path",
        "queryStringParameters" : {
            "multiValuedParameter" : [ {
                "schema" : {
                    "type" : "string",
                    "pattern" : "^[A-Z0-9-]+$"
                }
            } ],
            "maxItemCount" : [ {
                "schema" : {
                    "type" : "integer"
                }
            } ]
        }
    },
    "httpResponse" : {
        "body" : "some_response_body"
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import Expectation

client = MockServerClient("localhost", 1080)
client.upsert(Expectation.from_dict({
    "httpRequest" : {
        "path" : "/some/path",
        "queryStringParameters" : {
            "multiValuedParameter" : [ {
                "schema" : {
                    "type" : "string",
                    "pattern" : "^[A-Z0-9-]+$"
                }
            } ],
            "maxItemCount" : [ {
                "schema" : {
                    "type" : "integer"
                }
            } ]
        }
    },
    "httpResponse" : {
        "body" : "some_response_body"
    }
}))
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.upsert(MockServer::Expectation.from_hash({
    "httpRequest" : {
        "path" : "/some/path",
        "queryStringParameters" : {
            "multiValuedParameter" : [ {
                "schema" : {
                    "type" : "string",
                    "pattern" : "^[A-Z0-9-]+$"
                }
            } ],
            "maxItemCount" : [ {
                "schema" : {
                    "type" : "integer"
                }
            } ]
        }
    },
    "httpResponse" : {
        "body" : "some_response_body"
    }
}))
package main

import (
    "bytes"
    "net/http"
)

func main() {
    body := []byte(`{
    "httpRequest" : {
        "path" : "/some/path",
        "queryStringParameters" : {
            "multiValuedParameter" : [ {
                "schema" : {
                    "type" : "string",
                    "pattern" : "^[A-Z0-9-]+$"
                }
            } ],
            "maxItemCount" : [ {
                "schema" : {
                    "type" : "integer"
                }
            } ]
        }
    },
    "httpResponse" : {
        "body" : "some_response_body"
    }
}`)
    req, _ := http.NewRequest("PUT",
        "http://localhost:1080/mockserver/expectation",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    http.DefaultClient.Do(req)
}
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
    ""httpRequest"" : {
        ""path"" : ""/some/path"",
        ""queryStringParameters"" : {
            ""multiValuedParameter"" : [ {
                ""schema"" : {
                    ""type"" : ""string"",
                    ""pattern"" : ""^[A-Z0-9-]+$""
                }
            } ],
            ""maxItemCount"" : [ {
                ""schema"" : {
                    ""type"" : ""integer""
                }
            } ]
        }
    },
    ""httpResponse"" : {
        ""body"" : ""some_response_body""
    }
}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
    "httpRequest" : {
        "path" : "/some/path",
        "queryStringParameters" : {
            "multiValuedParameter" : [ {
                "schema" : {
                    "type" : "string",
                    "pattern" : "^[A-Z0-9-]+$"
                }
            } ],
            "maxItemCount" : [ {
                "schema" : {
                    "type" : "integer"
                }
            } ]
        }
    },
    "httpResponse" : {
        "body" : "some_response_body"
    }
}"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
$json = <<<'JSON'
{
    "httpRequest" : {
        "path" : "/some/path",
        "queryStringParameters" : {
            "multiValuedParameter" : [ {
                "schema" : {
                    "type" : "string",
                    "pattern" : "^[A-Z0-9-]+$"
                }
            } ],
            "maxItemCount" : [ {
                "schema" : {
                    "type" : "integer"
                }
            } ]
        }
    },
    "httpResponse" : {
        "body" : "some_response_body"
    }
}
JSON;

$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_POSTFIELDS     => $json,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json; charset=utf-8'],
    CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
curl_close($ch);

Matching by SUB_SET is the default mode so nothing needs to be specified for this key match style.

curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest" : {
        "path" : "/some/path",
        "queryStringParameters" : {
            "multiValuedParameter" : [ {
                "schema" : {
                    "type" : "string",
                    "pattern" : "^[A-Z0-9-]+$"
                }
            } ],
            "maxItemCount" : [ {
                "schema" : {
                    "type" : "integer"
                }
            } ]
        }
    },
    "httpResponse" : {
        "body" : "some_response_body"
    }
}'

See REST API for full JSON specification

Matching by keys to multiple-values by SUB_SET is the default mode this ensures at least one value with the same key matches, but MATCHING_KEY is also supported which ensures all values with the same key match.

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/some/path")
            .withQueryStringParameters(new Parameters(
                schemaParam("multiValuedParameter", "{\"type\": \"string\", \"pattern\": \"^[A-Z0-9\\-]+$\"}"),
                param(string("maxItemCount"), schemaString("{ \"type\": \"integer\" }"))
            ).withKeyMatchStyle(KeyMatchStyle.MATCHING_KEY))
    )
    .respond(
        response()
            .withBody("some_response_body")
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest" : {
        "path" : "/some/path",
        "queryStringParameters" : {
            "keyMatchStyle" : "MATCHING_KEY",
            "multiValuedParameter" : [ {
                "schema" : {
                    "type" : "string",
                    "pattern" : "^[A-Z0-9-]+$"
                }
            } ],
            "maxItemCount" : [ {
                "schema" : {
                    "type" : "integer"
                }
            } ]
        }
    },
    "httpResponse" : {
        "body" : "some_response_body"
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import Expectation

client = MockServerClient("localhost", 1080)
client.upsert(Expectation.from_dict({
    "httpRequest" : {
        "path" : "/some/path",
        "queryStringParameters" : {
            "keyMatchStyle" : "MATCHING_KEY",
            "multiValuedParameter" : [ {
                "schema" : {
                    "type" : "string",
                    "pattern" : "^[A-Z0-9-]+$"
                }
            } ],
            "maxItemCount" : [ {
                "schema" : {
                    "type" : "integer"
                }
            } ]
        }
    },
    "httpResponse" : {
        "body" : "some_response_body"
    }
}))
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.upsert(MockServer::Expectation.from_hash({
    "httpRequest" : {
        "path" : "/some/path",
        "queryStringParameters" : {
            "keyMatchStyle" : "MATCHING_KEY",
            "multiValuedParameter" : [ {
                "schema" : {
                    "type" : "string",
                    "pattern" : "^[A-Z0-9-]+$"
                }
            } ],
            "maxItemCount" : [ {
                "schema" : {
                    "type" : "integer"
                }
            } ]
        }
    },
    "httpResponse" : {
        "body" : "some_response_body"
    }
}))
package main

import (
    "bytes"
    "net/http"
)

func main() {
    body := []byte(`{
    "httpRequest" : {
        "path" : "/some/path",
        "queryStringParameters" : {
            "keyMatchStyle" : "MATCHING_KEY",
            "multiValuedParameter" : [ {
                "schema" : {
                    "type" : "string",
                    "pattern" : "^[A-Z0-9-]+$"
                }
            } ],
            "maxItemCount" : [ {
                "schema" : {
                    "type" : "integer"
                }
            } ]
        }
    },
    "httpResponse" : {
        "body" : "some_response_body"
    }
}`)
    req, _ := http.NewRequest("PUT",
        "http://localhost:1080/mockserver/expectation",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    http.DefaultClient.Do(req)
}
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
    ""httpRequest"" : {
        ""path"" : ""/some/path"",
        ""queryStringParameters"" : {
            ""keyMatchStyle"" : ""MATCHING_KEY"",
            ""multiValuedParameter"" : [ {
                ""schema"" : {
                    ""type"" : ""string"",
                    ""pattern"" : ""^[A-Z0-9-]+$""
                }
            } ],
            ""maxItemCount"" : [ {
                ""schema"" : {
                    ""type"" : ""integer""
                }
            } ]
        }
    },
    ""httpResponse"" : {
        ""body"" : ""some_response_body""
    }
}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
    "httpRequest" : {
        "path" : "/some/path",
        "queryStringParameters" : {
            "keyMatchStyle" : "MATCHING_KEY",
            "multiValuedParameter" : [ {
                "schema" : {
                    "type" : "string",
                    "pattern" : "^[A-Z0-9-]+$"
                }
            } ],
            "maxItemCount" : [ {
                "schema" : {
                    "type" : "integer"
                }
            } ]
        }
    },
    "httpResponse" : {
        "body" : "some_response_body"
    }
}"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
$json = <<<'JSON'
{
    "httpRequest" : {
        "path" : "/some/path",
        "queryStringParameters" : {
            "keyMatchStyle" : "MATCHING_KEY",
            "multiValuedParameter" : [ {
                "schema" : {
                    "type" : "string",
                    "pattern" : "^[A-Z0-9-]+$"
                }
            } ],
            "maxItemCount" : [ {
                "schema" : {
                    "type" : "integer"
                }
            } ]
        }
    },
    "httpResponse" : {
        "body" : "some_response_body"
    }
}
JSON;

$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_POSTFIELDS     => $json,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json; charset=utf-8'],
    CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
curl_close($ch);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest" : {
        "path" : "/some/path",
        "queryStringParameters" : {
            "keyMatchStyle" : "MATCHING_KEY",
            "multiValuedParameter" : [ {
                "schema" : {
                    "type" : "string",
                    "pattern" : "^[A-Z0-9-]+$"
                }
            } ],
            "maxItemCount" : [ {
                "schema" : {
                    "type" : "integer"
                }
            } ]
        }
    },
    "httpResponse" : {
        "body" : "some_response_body"
    }
}'

See REST API for full JSON specification

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withMethod("GET")
            .withPath("/some/path")
            .withHeaders(
                header("Accept", "application/json"),
                header("Accept-Encoding", "gzip, deflate, br")
            )
    )
    .respond(
        response()
            .withBody("some_response_body")
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "method": "GET",
        "path": "/some/path",
        "headers": {
            "Accept": ["application/json"],
            "Accept-Encoding": ["gzip, deflate, br"]
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import HttpRequest, HttpResponse

client = MockServerClient("localhost", 1080)
client.when(
    HttpRequest.request("/some/path")
        .with_method("GET")
        .with_header("Accept", "application/json")
        .with_header("Accept-Encoding", "gzip, deflate, br")
).respond(
    HttpResponse.response(body="some_response_body")
)
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.when(
    MockServer::HttpRequest.new(path: '/some/path', method: 'GET')
).respond(
    MockServer::HttpResponse.new(body: 'some_response_body')
)
import mockserver "github.com/mock-server/mockserver-monorepo/mockserver-client-go"

client := mockserver.New("localhost", 1080)
client.When(
    mockserver.Request().Path("/some/path").Method("GET").Header("Accept", "application/json").Header("Accept-Encoding", "gzip, deflate, br"),
).Respond(
    mockserver.Response().Body("some_response_body"),
)
using MockServer.Client;
using MockServer.Client.Models;

using var client = new MockServerClient("localhost", 1080);
client.When(
    HttpRequest.Request().WithPath("/some/path").WithMethod("GET").WithHeader("Accept", "application/json").WithHeader("Accept-Encoding", "gzip, deflate, br")
).Respond(
    HttpResponse.Response().WithBody("some_response_body")
);
use mockserver_client::{ClientBuilder, HttpRequest, HttpResponse};

let client = ClientBuilder::new("localhost", 1080).build().unwrap();
client.when(HttpRequest::new().method("GET").path("/some/path").header("Accept", "application/json").header("Accept-Encoding", "gzip, deflate, br"))
    .respond(HttpResponse::new().body("some_response_body"))
    .unwrap();
use MockServer\MockServerClient;
use MockServer\HttpRequest;
use MockServer\HttpResponse;

$client = new MockServerClient('localhost', 1080);
$client->when(
    HttpRequest::request()
        ->method('GET')
        ->path('/some/path')
        ->header('Accept', 'application/json')
        ->header('Accept-Encoding', 'gzip, deflate, br')
)->respond(
    HttpResponse::response()
        ->body('some_response_body')
);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
  "httpRequest" : {
    "method" : "GET",
    "path" : "/some/path",
    "headers" : {
      "Accept" : [ "application/json" ],
      "Accept-Encoding" : [ "gzip, deflate, br" ]
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}'

See REST API for full JSON specification

For details of the full regex syntax supported please see the JDK documentation.

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/some/path")
            .withHeader(
                header("Accept.*")
            )
    )
    .respond(
        response()
            .withBody("some_response_body")
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "path": "/some/path",
        "headers": {
            // matches requests that have any header starting with the name Accept
            "Accept.*": [ "" ]
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import HttpRequest, HttpResponse

client = MockServerClient("localhost", 1080)
client.when(
    HttpRequest.request("/some/path")
        .with_header("Accept.*", "")
).respond(
    HttpResponse.response(body="some_response_body")
)
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.when(
    MockServer::HttpRequest.new(path: '/some/path')
).respond(
    MockServer::HttpResponse.new(body: 'some_response_body')
)
import mockserver "github.com/mock-server/mockserver-monorepo/mockserver-client-go"

client := mockserver.New("localhost", 1080)
client.When(
    mockserver.Request().Path("/some/path").Header("Accept.*", ""),
).Respond(
    mockserver.Response().Body("some_response_body"),
)
using MockServer.Client;
using MockServer.Client.Models;

using var client = new MockServerClient("localhost", 1080);
client.When(
    HttpRequest.Request().WithPath("/some/path").WithHeader("Accept.*", "")
).Respond(
    HttpResponse.Response().WithBody("some_response_body")
);
use mockserver_client::{ClientBuilder, HttpRequest, HttpResponse};

let client = ClientBuilder::new("localhost", 1080).build().unwrap();
client.when(HttpRequest::new().path("/some/path").header("Accept.*", ""))
    .respond(HttpResponse::new().body("some_response_body"))
    .unwrap();
use MockServer\MockServerClient;
use MockServer\HttpRequest;
use MockServer\HttpResponse;

$client = new MockServerClient('localhost', 1080);
$client->when(
    HttpRequest::request()
        ->path('/some/path')
        ->header('Accept.*', '')
)->respond(
    HttpResponse::response()
        ->body('some_response_body')
);
// matches requests that have any header starting with the name Accept
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest": {
        "path": "/some/path",
        "headers": {
            "Accept.*": [ "" ]
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}'

See REST API for full JSON specification

For details of the full regex syntax supported please see the JDK documentation.

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/some/path")
            .withHeader(
                header("Accept.*", ".*gzip.*")
            )
    )
    .respond(
        response()
            .withBody("some_response_body")
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "path": "/some/path",
        "headers": {
            // matches requests that have a header with a name starting with Accept and a value containing gzip
            "Accept.*": [".*gzip.*"]
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import HttpRequest, HttpResponse

client = MockServerClient("localhost", 1080)
client.when(
    HttpRequest.request("/some/path")
        .with_header("Accept.*", ".*gzip.*")
).respond(
    HttpResponse.response(body="some_response_body")
)
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.when(
    MockServer::HttpRequest.new(path: '/some/path')
).respond(
    MockServer::HttpResponse.new(body: 'some_response_body')
)
import mockserver "github.com/mock-server/mockserver-monorepo/mockserver-client-go"

client := mockserver.New("localhost", 1080)
client.When(
    mockserver.Request().Path("/some/path").Header("Accept.*", ".*gzip.*"),
).Respond(
    mockserver.Response().Body("some_response_body"),
)
using MockServer.Client;
using MockServer.Client.Models;

using var client = new MockServerClient("localhost", 1080);
client.When(
    HttpRequest.Request().WithPath("/some/path").WithHeader("Accept.*", ".*gzip.*")
).Respond(
    HttpResponse.Response().WithBody("some_response_body")
);
use mockserver_client::{ClientBuilder, HttpRequest, HttpResponse};

let client = ClientBuilder::new("localhost", 1080).build().unwrap();
client.when(HttpRequest::new().path("/some/path").header("Accept.*", ".*gzip.*"))
    .respond(HttpResponse::new().body("some_response_body"))
    .unwrap();
use MockServer\MockServerClient;
use MockServer\HttpRequest;
use MockServer\HttpResponse;

$client = new MockServerClient('localhost', 1080);
$client->when(
    HttpRequest::request()
        ->path('/some/path')
        ->header('Accept.*', '.*gzip.*')
)->respond(
    HttpResponse::response()
        ->body('some_response_body')
);
// matches requests that have a header with a name starting with Accept and a value containing gzip
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest": {
        "path": "/some/path",
        "headers": {
            "Accept.*": [".*gzip.*"]
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}'

See REST API for full JSON specification

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/some/path")
            .withHeaders(
                // matches requests that have an Accept header without the value "application/json"
                header(string("Accept"), not("application/json")),
                // matches requests that have an Accept-Encoding without the substring "gzip"
                header(string("Accept-Encoding"), not(".*gzip.*"))
            )
    )
    .respond(
        response()
            .withBody("some_response_body")
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "path": "/some/path",
        "headers": {
            // matches requests that have an Accept header without the value "application/json"
            "Accept": ["!application/json"],
            // matches requests that have an Accept-Encoding without the substring "gzip"
            "Accept-Encoding": ["!.*gzip.*"]
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import Expectation

client = MockServerClient("localhost", 1080)
client.upsert(Expectation.from_dict({
  "httpRequest" : {
    "path" : "/some/path",
    "headers" : {
      "Accept" : [ "!application/json" ],
      "Accept-Encoding" : [ "!.*gzip.*" ]
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}))
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.upsert(MockServer::Expectation.from_hash({
  "httpRequest" : {
    "path" : "/some/path",
    "headers" : {
      "Accept" : [ "!application/json" ],
      "Accept-Encoding" : [ "!.*gzip.*" ]
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}))
package main

import (
    "bytes"
    "net/http"
)

func main() {
    body := []byte(`{
  "httpRequest" : {
    "path" : "/some/path",
    "headers" : {
      "Accept" : [ "!application/json" ],
      "Accept-Encoding" : [ "!.*gzip.*" ]
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}`)
    req, _ := http.NewRequest("PUT",
        "http://localhost:1080/mockserver/expectation",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    http.DefaultClient.Do(req)
}
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
  ""httpRequest"" : {
    ""path"" : ""/some/path"",
    ""headers"" : {
      ""Accept"" : [ ""!application/json"" ],
      ""Accept-Encoding"" : [ ""!.*gzip.*"" ]
    }
  },
  ""httpResponse"" : {
    ""body"" : ""some_response_body""
  }
}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
  "httpRequest" : {
    "path" : "/some/path",
    "headers" : {
      "Accept" : [ "!application/json" ],
      "Accept-Encoding" : [ "!.*gzip.*" ]
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
$json = <<<'JSON'
{
  "httpRequest" : {
    "path" : "/some/path",
    "headers" : {
      "Accept" : [ "!application/json" ],
      "Accept-Encoding" : [ "!.*gzip.*" ]
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}
JSON;

$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_POSTFIELDS     => $json,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json; charset=utf-8'],
    CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
curl_close($ch);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
  "httpRequest" : {
    "path" : "/some/path",
    "headers" : {
      "Accept" : [ "!application/json" ],
      "Accept-Encoding" : [ "!.*gzip.*" ]
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}'

See REST API for full JSON specification

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/some/path")
            .withHeaders(
                // matches requests that do not have either an Accept or an Accept-Encoding header
                header(not("Accept")),
                header(not("Accept-Encoding"))
            )
    )
    .respond(
        response()
            .withBody("some_response_body")
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "path": "/some/path",
        "headers": {
            // matches requests that do not have either an Accept or an Accept-Encoding header
            "!Accept": [".*"],
            "!Accept-Encoding": [".*"]
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import Expectation

client = MockServerClient("localhost", 1080)
client.upsert(Expectation.from_dict({
  "httpRequest" : {
    "path" : "/some/path",
    "headers" : {
      "!Accept" : [ ".*" ],
      "!Accept-Encoding" : [ ".*" ]
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}))
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.upsert(MockServer::Expectation.from_hash({
  "httpRequest" : {
    "path" : "/some/path",
    "headers" : {
      "!Accept" : [ ".*" ],
      "!Accept-Encoding" : [ ".*" ]
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}))
package main

import (
    "bytes"
    "net/http"
)

func main() {
    body := []byte(`{
  "httpRequest" : {
    "path" : "/some/path",
    "headers" : {
      "!Accept" : [ ".*" ],
      "!Accept-Encoding" : [ ".*" ]
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}`)
    req, _ := http.NewRequest("PUT",
        "http://localhost:1080/mockserver/expectation",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    http.DefaultClient.Do(req)
}
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
  ""httpRequest"" : {
    ""path"" : ""/some/path"",
    ""headers"" : {
      ""!Accept"" : [ "".*"" ],
      ""!Accept-Encoding"" : [ "".*"" ]
    }
  },
  ""httpResponse"" : {
    ""body"" : ""some_response_body""
  }
}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
  "httpRequest" : {
    "path" : "/some/path",
    "headers" : {
      "!Accept" : [ ".*" ],
      "!Accept-Encoding" : [ ".*" ]
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
$json = <<<'JSON'
{
  "httpRequest" : {
    "path" : "/some/path",
    "headers" : {
      "!Accept" : [ ".*" ],
      "!Accept-Encoding" : [ ".*" ]
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}
JSON;

$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_POSTFIELDS     => $json,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json; charset=utf-8'],
    CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
curl_close($ch);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
  "httpRequest" : {
    "path" : "/some/path",
    "headers" : {
      "!Accept" : [ ".*" ],
      "!Accept-Encoding" : [ ".*" ]
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}'

See REST API for full JSON specification

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/some/path")
            .withHeader(
                schemaHeader("Accept.*", "{\"type\": \"string\", \"pattern\": \"^.*gzip.*$\"}")
            )
    )
    .respond(
        response()
            .withBody("some_response_body")
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "path": "/some/path",
        "headers": {
            "Accept.*": [{
                "schema": {
                    "type": "string",
                    "pattern": "^.*gzip.*$"
                }
            }]
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import Expectation

client = MockServerClient("localhost", 1080)
client.upsert(Expectation.from_dict({
    "httpRequest": {
        "path": "/some/path",
        "headers": {
            "Accept.*": [{
                "schema": {
                    "type": "string",
                    "pattern": "^.*gzip.*$"
                }
            }]
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}))
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.upsert(MockServer::Expectation.from_hash({
    "httpRequest": {
        "path": "/some/path",
        "headers": {
            "Accept.*": [{
                "schema": {
                    "type": "string",
                    "pattern": "^.*gzip.*$"
                }
            }]
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}))
package main

import (
    "bytes"
    "net/http"
)

func main() {
    body := []byte(`{
    "httpRequest": {
        "path": "/some/path",
        "headers": {
            "Accept.*": [{
                "schema": {
                    "type": "string",
                    "pattern": "^.*gzip.*$"
                }
            }]
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}`)
    req, _ := http.NewRequest("PUT",
        "http://localhost:1080/mockserver/expectation",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    http.DefaultClient.Do(req)
}
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
    ""httpRequest"": {
        ""path"": ""/some/path"",
        ""headers"": {
            ""Accept.*"": [{
                ""schema"": {
                    ""type"": ""string"",
                    ""pattern"": ""^.*gzip.*$""
                }
            }]
        }
    },
    ""httpResponse"": {
        ""body"": ""some_response_body""
    }
}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
    "httpRequest": {
        "path": "/some/path",
        "headers": {
            "Accept.*": [{
                "schema": {
                    "type": "string",
                    "pattern": "^.*gzip.*$"
                }
            }]
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
$json = <<<'JSON'
{
    "httpRequest": {
        "path": "/some/path",
        "headers": {
            "Accept.*": [{
                "schema": {
                    "type": "string",
                    "pattern": "^.*gzip.*$"
                }
            }]
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}
JSON;

$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_POSTFIELDS     => $json,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json; charset=utf-8'],
    CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
curl_close($ch);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest": {
        "path": "/some/path",
        "headers": {
            "Accept.*": [{
                "schema": {
                    "type": "string",
                    "pattern": "^.*gzip.*$"
                }
            }]
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}'

See REST API for full JSON specification

This example shows how to match by either one value (in this case a header) or another value or both.

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/some/path")
            .withHeaders(
                header("headerOne|headerTwo", ".*"),
                optionalHeader("headerOne", "headerOneValue"),
                optionalHeader("headerTwo", "headerTwoValue")
            )
    )
    .respond(
        response()
            .withBody("some_response_body")
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "path": "/some/path",
        "headers": {
            "headerOne|headerTwo": [".*"],
            "?headerOne": ["headerOneValue"],
            "?headerTwo": ["headerTwoValue"]
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import HttpRequest, HttpResponse

client = MockServerClient("localhost", 1080)
client.when(
    HttpRequest.request("/some/path")
        .with_header("headerOne|headerTwo", ".*")
        .with_header("?headerOne", "headerOneValue")
        .with_header("?headerTwo", "headerTwoValue")
).respond(
    HttpResponse.response(body="some_response_body")
)
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.when(
    MockServer::HttpRequest.new(path: '/some/path')
).respond(
    MockServer::HttpResponse.new(body: 'some_response_body')
)
import mockserver "github.com/mock-server/mockserver-monorepo/mockserver-client-go"

client := mockserver.New("localhost", 1080)
client.When(
    mockserver.Request().Path("/some/path").Header("headerOne|headerTwo", ".*").Header("?headerOne", "headerOneValue").Header("?headerTwo", "headerTwoValue"),
).Respond(
    mockserver.Response().Body("some_response_body"),
)
using MockServer.Client;
using MockServer.Client.Models;

using var client = new MockServerClient("localhost", 1080);
client.When(
    HttpRequest.Request().WithPath("/some/path").WithHeader("headerOne|headerTwo", ".*").WithHeader("?headerOne", "headerOneValue").WithHeader("?headerTwo", "headerTwoValue")
).Respond(
    HttpResponse.Response().WithBody("some_response_body")
);
use mockserver_client::{ClientBuilder, HttpRequest, HttpResponse};

let client = ClientBuilder::new("localhost", 1080).build().unwrap();
client.when(HttpRequest::new().path("/some/path").header("headerOne|headerTwo", ".*").header("?headerOne", "headerOneValue").header("?headerTwo", "headerTwoValue"))
    .respond(HttpResponse::new().body("some_response_body"))
    .unwrap();
use MockServer\MockServerClient;
use MockServer\HttpRequest;
use MockServer\HttpResponse;

$client = new MockServerClient('localhost', 1080);
$client->when(
    HttpRequest::request()
        ->path('/some/path')
        ->header('headerOne|headerTwo', '.*')
        ->header('?headerOne', 'headerOneValue')
        ->header('?headerTwo', 'headerTwoValue')
)->respond(
    HttpResponse::response()
        ->body('some_response_body')
);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest": {
        "path": "/some/path",
        "headers": {
            "headerOne|headerTwo": [".*"],
            "?headerOne": ["headerOneValue"],
            "?headerTwo": ["headerTwoValue"]
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}'

See REST API for full JSON specification

Matching by keys to multiple-values by SUB_SET is the default mode this ensures at least one value with the same key matches, but MATCHING_KEY is also supported which ensures all values with the same key match.

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/some/path")
            .withHeaders(new Headers(
                header("multiValuedHeader", "value.*"),
                header("headerTwo", "headerTwoValue")
            ).withKeyMatchStyle(KeyMatchStyle.MATCHING_KEY))
    )
    .respond(
        response()
            .withBody("some_response_body")
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest" : {
        "path" : "/some/path",
        "headers" : {
            "keyMatchStyle" : "MATCHING_KEY",
            "multiValuedHeader" : [ "value.*" ],
            "headerTwo" : [ "headerTwoValue" ]
        }
    },
    "httpResponse" : {
        "body" : "some_response_body"
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import HttpRequest, HttpResponse

client = MockServerClient("localhost", 1080)
client.when(
    HttpRequest.request("/some/path")
        .with_header("keyMatchStyle", "M", "A", "T", "C", "H", "I", "N", "G", "_", "K", "E", "Y")
        .with_header("multiValuedHeader", "value.*")
        .with_header("headerTwo", "headerTwoValue")
).respond(
    HttpResponse.response(body="some_response_body")
)
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.when(
    MockServer::HttpRequest.new(path: '/some/path')
).respond(
    MockServer::HttpResponse.new(body: 'some_response_body')
)
import mockserver "github.com/mock-server/mockserver-monorepo/mockserver-client-go"

client := mockserver.New("localhost", 1080)
client.When(
    mockserver.Request().Path("/some/path").Header("keyMatchStyle", "M", "A", "T", "C", "H", "I", "N", "G", "_", "K", "E", "Y").Header("multiValuedHeader", "value.*").Header("headerTwo", "headerTwoValue"),
).Respond(
    mockserver.Response().Body("some_response_body"),
)
using MockServer.Client;
using MockServer.Client.Models;

using var client = new MockServerClient("localhost", 1080);
client.When(
    HttpRequest.Request().WithPath("/some/path").WithHeader("keyMatchStyle", "M", "A", "T", "C", "H", "I", "N", "G", "_", "K", "E", "Y").WithHeader("multiValuedHeader", "value.*").WithHeader("headerTwo", "headerTwoValue")
).Respond(
    HttpResponse.Response().WithBody("some_response_body")
);
use mockserver_client::{ClientBuilder, HttpRequest, HttpResponse};

let client = ClientBuilder::new("localhost", 1080).build().unwrap();
client.when(HttpRequest::new().path("/some/path").header("keyMatchStyle", "M").header("keyMatchStyle", "A").header("keyMatchStyle", "T").header("keyMatchStyle", "C").header("keyMatchStyle", "H").header("keyMatchStyle", "I").header("keyMatchStyle", "N").header("keyMatchStyle", "G").header("keyMatchStyle", "_").header("keyMatchStyle", "K").header("keyMatchStyle", "E").header("keyMatchStyle", "Y").header("multiValuedHeader", "value.*").header("headerTwo", "headerTwoValue"))
    .respond(HttpResponse::new().body("some_response_body"))
    .unwrap();
use MockServer\MockServerClient;
use MockServer\HttpRequest;
use MockServer\HttpResponse;

$client = new MockServerClient('localhost', 1080);
$client->when(
    HttpRequest::request()
        ->path('/some/path')
        ->header('keyMatchStyle', 'MATCHING_KEY')
        ->header('multiValuedHeader', 'value.*')
        ->header('headerTwo', 'headerTwoValue')
)->respond(
    HttpResponse::response()
        ->body('some_response_body')
);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest" : {
        "path" : "/some/path",
        "headers" : {
            "keyMatchStyle" : "MATCHING_KEY",
            "multiValuedHeader" : [ "value.*" ],
            "headerTwo" : [ "headerTwoValue" ]
        }
    },
    "httpResponse" : {
        "body" : "some_response_body"
    }
}'

See REST API for full JSON specification

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withMethod("GET")
            .withPath("/view/cart")
            .withCookies(
                cookie("session", "4930456C-C718-476F-971F-CB8E047AB349")
            )
            .withQueryStringParameters(
                param("cartId", "055CA455-1DF7-45BB-8535-4F83E7266092")
            )
    )
    .respond(
        response()
            .withBody("some_response_body")
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "method": "GET",
        "path": "/view/cart",
        "queryStringParameters": {
            "cartId": ["055CA455-1DF7-45BB-8535-4F83E7266092"]
        },
        "cookies": {
            "session": "4930456C-C718-476F-971F-CB8E047AB349"
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import HttpRequest, HttpResponse

client = MockServerClient("localhost", 1080)
client.when(
    HttpRequest.request("/view/cart")
        .with_method("GET")
        .with_query_param("cartId", "055CA455-1DF7-45BB-8535-4F83E7266092")
        .with_cookie("session", "4930456C-C718-476F-971F-CB8E047AB349")
).respond(
    HttpResponse.response(body="some_response_body")
)
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.when(
    MockServer::HttpRequest.new(path: '/view/cart', method: 'GET')
).respond(
    MockServer::HttpResponse.new(body: 'some_response_body')
)
import mockserver "github.com/mock-server/mockserver-monorepo/mockserver-client-go"

client := mockserver.New("localhost", 1080)
client.When(
    mockserver.Request().Path("/view/cart").Method("GET").QueryStringParameter("cartId", "055CA455-1DF7-45BB-8535-4F83E7266092").Cookie("session", "4930456C-C718-476F-971F-CB8E047AB349"),
).Respond(
    mockserver.Response().Body("some_response_body"),
)
using MockServer.Client;
using MockServer.Client.Models;

using var client = new MockServerClient("localhost", 1080);
client.When(
    HttpRequest.Request().WithPath("/view/cart").WithMethod("GET").WithQueryStringParameter("cartId", "055CA455-1DF7-45BB-8535-4F83E7266092")
).Respond(
    HttpResponse.Response().WithBody("some_response_body")
);
use mockserver_client::{ClientBuilder, HttpRequest, HttpResponse};

let client = ClientBuilder::new("localhost", 1080).build().unwrap();
client.when(HttpRequest::new().method("GET").path("/view/cart").query_param("cartId", "055CA455-1DF7-45BB-8535-4F83E7266092"))
    .respond(HttpResponse::new().body("some_response_body"))
    .unwrap();
use MockServer\MockServerClient;
use MockServer\HttpRequest;
use MockServer\HttpResponse;

$client = new MockServerClient('localhost', 1080);
$client->when(
    HttpRequest::request()
        ->method('GET')
        ->path('/view/cart')
        ->queryStringParameter('cartId', '055CA455-1DF7-45BB-8535-4F83E7266092')
        ->cookie('session', '4930456C-C718-476F-971F-CB8E047AB349')
)->respond(
    HttpResponse::response()
        ->body('some_response_body')
);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
  "httpRequest" : {
    "method" : "GET",
    "path" : "/view/cart",
    "queryStringParameters" : {
      "cartId" : [ "055CA455-1DF7-45BB-8535-4F83E7266092" ]
    },
    "cookies" : {
      "session" : "4930456C-C718-476F-971F-CB8E047AB349"
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}'

See REST API for full JSON specification

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withMethod("GET")
            .withPath("/view/cart")
            .withQueryStringParameters(
                schemaParam("cartId", "{ \"type\": \"string\", \"format\": \"uuid\" }")
            )
            .withCookies(
                schemaCookie("session", "{ \"type\": \"string\", \"format\": \"uuid\" }")
            )
    )
    .respond(
        response()
            .withBody("some_response_body")
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "method": "GET",
        "path": "/view/cart",
        "queryStringParameters": {
            "cartId": [{
                "schema": {
                    "type": "string",
                    "format": "uuid"
                }
            }]
        },
        "cookies": {
            "session": {
                "schema": {
                    "type": "string",
                    "format": "uuid"
                }
            }
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import HttpRequest, HttpResponse

client = MockServerClient("localhost", 1080)
client.when(
    HttpRequest.request("/view/cart")
        .with_method("GET")
        .with_query_param("cartId", "055CA455-1DF7-45BB-8535-4F83E7266092")
        .with_cookie("session", "4930456C-C718-476F-971F-CB8E047AB349")
).respond(
    HttpResponse.response(body="some_response_body")
)
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.when(
    MockServer::HttpRequest.new(path: '/view/cart', method: 'GET')
).respond(
    MockServer::HttpResponse.new(body: 'some_response_body')
)
import mockserver "github.com/mock-server/mockserver-monorepo/mockserver-client-go"

client := mockserver.New("localhost", 1080)
client.When(
    mockserver.Request().Path("/view/cart").Method("GET").QueryStringParameter("cartId", "055CA455-1DF7-45BB-8535-4F83E7266092").Cookie("session", "4930456C-C718-476F-971F-CB8E047AB349"),
).Respond(
    mockserver.Response().Body("some_response_body"),
)
using MockServer.Client;
using MockServer.Client.Models;

using var client = new MockServerClient("localhost", 1080);
client.When(
    HttpRequest.Request().WithPath("/view/cart").WithMethod("GET").WithQueryStringParameter("cartId", "055CA455-1DF7-45BB-8535-4F83E7266092")
).Respond(
    HttpResponse.Response().WithBody("some_response_body")
);
use mockserver_client::{ClientBuilder, HttpRequest, HttpResponse};

let client = ClientBuilder::new("localhost", 1080).build().unwrap();
client.when(HttpRequest::new().method("GET").path("/view/cart").query_param("cartId", "055CA455-1DF7-45BB-8535-4F83E7266092"))
    .respond(HttpResponse::new().body("some_response_body"))
    .unwrap();
use MockServer\MockServerClient;
use MockServer\HttpRequest;
use MockServer\HttpResponse;

$client = new MockServerClient('localhost', 1080);
$client->when(
    HttpRequest::request()
        ->method('GET')
        ->path('/view/cart')
        ->queryStringParameter('cartId', '055CA455-1DF7-45BB-8535-4F83E7266092')
        ->cookie('session', '4930456C-C718-476F-971F-CB8E047AB349')
)->respond(
    HttpResponse::response()
        ->body('some_response_body')
);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
  "httpRequest" : {
    "method" : "GET",
    "path" : "/view/cart",
    "queryStringParameters" : {
      "cartId" : [ "055CA455-1DF7-45BB-8535-4F83E7266092" ]
    },
    "cookies" : {
      "session" : "4930456C-C718-476F-971F-CB8E047AB349"
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}'

See REST API for full JSON specification

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/view/cart")
            .withCookies(
                optionalCookie("session", schemaString("{ \"type\": \"string\", \"format\": \"uuid\" }"))
            )
            .withQueryStringParameters(
                schemaParam("cartId", "{ \"type\": \"string\", \"format\": \"uuid\" }")
            )
    )
    .respond(
        response()
            .withBody("some_response_body")
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "path": "/view/cart",
        "queryStringParameters": {
            "cartId": [{
                "schema": {
                    "type": "string",
                    "format": "uuid"
                }
            }]
        },
        "cookies": {
            "?session": {
                "schema": {
                    "type": "string",
                    "format": "uuid"
                }
            }
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import Expectation

client = MockServerClient("localhost", 1080)
client.upsert(Expectation.from_dict({
    "httpRequest": {
        "path": "/view/cart",
        "queryStringParameters": {
            "cartId": [{
                "schema": {
                    "type": "string",
                    "format": "uuid"
                }
            }]
        },
        "cookies": {
            "?session": {
                "schema": {
                    "type": "string",
                    "format": "uuid"
                }
            }
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}))
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.upsert(MockServer::Expectation.from_hash({
    "httpRequest": {
        "path": "/view/cart",
        "queryStringParameters": {
            "cartId": [{
                "schema": {
                    "type": "string",
                    "format": "uuid"
                }
            }]
        },
        "cookies": {
            "?session": {
                "schema": {
                    "type": "string",
                    "format": "uuid"
                }
            }
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}))
package main

import (
    "bytes"
    "net/http"
)

func main() {
    body := []byte(`{
    "httpRequest": {
        "path": "/view/cart",
        "queryStringParameters": {
            "cartId": [{
                "schema": {
                    "type": "string",
                    "format": "uuid"
                }
            }]
        },
        "cookies": {
            "?session": {
                "schema": {
                    "type": "string",
                    "format": "uuid"
                }
            }
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}`)
    req, _ := http.NewRequest("PUT",
        "http://localhost:1080/mockserver/expectation",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    http.DefaultClient.Do(req)
}
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
    ""httpRequest"": {
        ""path"": ""/view/cart"",
        ""queryStringParameters"": {
            ""cartId"": [{
                ""schema"": {
                    ""type"": ""string"",
                    ""format"": ""uuid""
                }
            }]
        },
        ""cookies"": {
            ""?session"": {
                ""schema"": {
                    ""type"": ""string"",
                    ""format"": ""uuid""
                }
            }
        }
    },
    ""httpResponse"": {
        ""body"": ""some_response_body""
    }
}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
    "httpRequest": {
        "path": "/view/cart",
        "queryStringParameters": {
            "cartId": [{
                "schema": {
                    "type": "string",
                    "format": "uuid"
                }
            }]
        },
        "cookies": {
            "?session": {
                "schema": {
                    "type": "string",
                    "format": "uuid"
                }
            }
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
$json = <<<'JSON'
{
    "httpRequest": {
        "path": "/view/cart",
        "queryStringParameters": {
            "cartId": [{
                "schema": {
                    "type": "string",
                    "format": "uuid"
                }
            }]
        },
        "cookies": {
            "?session": {
                "schema": {
                    "type": "string",
                    "format": "uuid"
                }
            }
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}
JSON;

$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_POSTFIELDS     => $json,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json; charset=utf-8'],
    CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
curl_close($ch);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest": {
        "path": "/view/cart",
        "queryStringParameters": {
            "cartId": [{
                "schema": {
                    "type": "string",
                    "format": "uuid"
                }
            }]
        },
        "cookies": {
            "?session": {
                "schema": {
                    "type": "string",
                    "format": "uuid"
                }
            }
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}'

See REST API for full JSON specification

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withBody(subString("some_string"))
    )
    .respond(
        response()
            .withBody("some_response_body")
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "body": {
            "type": "STRING",
            "string": "some_string",
            "subString": true
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import Expectation

client = MockServerClient("localhost", 1080)
client.upsert(Expectation.from_dict({
  "httpRequest" : {
    "body" : {
      "type": "STRING",
      "string": "some_string",
      "subString": True
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}))
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.upsert(MockServer::Expectation.from_hash({
  "httpRequest" : {
    "body" : {
      "type": "STRING",
      "string": "some_string",
      "subString": true
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}))
package main

import (
    "bytes"
    "net/http"
)

func main() {
    body := []byte(`{
  "httpRequest" : {
    "body" : {
      "type": "STRING",
      "string": "some_string",
      "subString": true
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}`)
    req, _ := http.NewRequest("PUT",
        "http://localhost:1080/mockserver/expectation",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    http.DefaultClient.Do(req)
}
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
  ""httpRequest"" : {
    ""body"" : {
      ""type"": ""STRING"",
      ""string"": ""some_string"",
      ""subString"": true
    }
  },
  ""httpResponse"" : {
    ""body"" : ""some_response_body""
  }
}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
  "httpRequest" : {
    "body" : {
      "type": "STRING",
      "string": "some_string",
      "subString": true
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
$json = <<<'JSON'
{
  "httpRequest" : {
    "body" : {
      "type": "STRING",
      "string": "some_string",
      "subString": true
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}
JSON;

$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_POSTFIELDS     => $json,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json; charset=utf-8'],
    CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
curl_close($ch);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
  "httpRequest" : {
    "body" : {
      "type": "STRING",
      "string": "some_string",
      "subString": true
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}'

See REST API for full JSON specification

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withBody(exact("我说中国话", Charsets.UTF_16))
    )
    .respond(
        response()
            .withBody("some_response_body")
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "body": {
            "type": "STRING",
            "string": "我说中国话",
            "contentType": "text/plain; charset=utf-16"
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import Expectation

client = MockServerClient("localhost", 1080)
client.upsert(Expectation.from_dict({
  "httpRequest" : {
    "body" : {
      "type" : "STRING",
      "string" : "我说中国话",
      "contentType" : "text/plain; charset=utf-16"
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}))
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.upsert(MockServer::Expectation.from_hash({
  "httpRequest" : {
    "body" : {
      "type" : "STRING",
      "string" : "我说中国话",
      "contentType" : "text/plain; charset=utf-16"
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}))
package main

import (
    "bytes"
    "net/http"
)

func main() {
    body := []byte(`{
  "httpRequest" : {
    "body" : {
      "type" : "STRING",
      "string" : "我说中国话",
      "contentType" : "text/plain; charset=utf-16"
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}`)
    req, _ := http.NewRequest("PUT",
        "http://localhost:1080/mockserver/expectation",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    http.DefaultClient.Do(req)
}
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
  ""httpRequest"" : {
    ""body"" : {
      ""type"" : ""STRING"",
      ""string"" : ""我说中国话"",
      ""contentType"" : ""text/plain; charset=utf-16""
    }
  },
  ""httpResponse"" : {
    ""body"" : ""some_response_body""
  }
}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
  "httpRequest" : {
    "body" : {
      "type" : "STRING",
      "string" : "我说中国话",
      "contentType" : "text/plain; charset=utf-16"
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
$json = <<<'JSON'
{
  "httpRequest" : {
    "body" : {
      "type" : "STRING",
      "string" : "我说中国话",
      "contentType" : "text/plain; charset=utf-16"
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}
JSON;

$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_POSTFIELDS     => $json,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json; charset=utf-8'],
    CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
curl_close($ch);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
  "httpRequest" : {
    "body" : {
      "type" : "STRING",
      "string" : "我说中国话",
      "contentType" : "text/plain; charset=utf-16"
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}'

See REST API for full JSON specification

For details of the full regex syntax supported please see the JDK documentation.

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withBody(regex("starts_with_.*"))
    )
    .respond(
        response()
            .withBody("some_response_body")
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "body": {
            "type": "REGEX",
            "regex": "starts_with_.*"
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import Expectation

client = MockServerClient("localhost", 1080)
client.upsert(Expectation.from_dict({
  "httpRequest": {
    "body": {
      "type": "REGEX",
      "regex": "starts_with_.*"
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}))
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.upsert(MockServer::Expectation.from_hash({
  "httpRequest": {
    "body": {
      "type": "REGEX",
      "regex": "starts_with_.*"
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}))
package main

import (
    "bytes"
    "net/http"
)

func main() {
    body := []byte(`{
  "httpRequest": {
    "body": {
      "type": "REGEX",
      "regex": "starts_with_.*"
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}`)
    req, _ := http.NewRequest("PUT",
        "http://localhost:1080/mockserver/expectation",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    http.DefaultClient.Do(req)
}
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
  ""httpRequest"": {
    ""body"": {
      ""type"": ""REGEX"",
      ""regex"": ""starts_with_.*""
    }
  },
  ""httpResponse"" : {
    ""body"" : ""some_response_body""
  }
}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
  "httpRequest": {
    "body": {
      "type": "REGEX",
      "regex": "starts_with_.*"
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
$json = <<<'JSON'
{
  "httpRequest": {
    "body": {
      "type": "REGEX",
      "regex": "starts_with_.*"
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}
JSON;

$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_POSTFIELDS     => $json,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json; charset=utf-8'],
    CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
curl_close($ch);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
  "httpRequest": {
    "body": {
      "type": "REGEX",
      "regex": "starts_with_.*"
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}'

See REST API for full JSON specification

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withMethod("POST")
            .withHeaders(
                header("Content-Type", "application/x-www-form-urlencoded")
            )
            .withBody(
                params(
                    param("email", "joe.blogs@gmail.com"),
                    param("password", "secure_Password123")
                )
            )
    )
    .respond(
        response()
            .withBody("some_response_body")
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "method": "POST",
        "headers": {
            "Content-Type": ["application/x-www-form-urlencoded"]
        },
        "body": {
            "type": "PARAMETERS",
            "parameters": {
                "email": ["joe.blogs@gmail.com"],
                "password": ["secure_Password123"]
            }
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import Expectation

client = MockServerClient("localhost", 1080)
client.upsert(Expectation.from_dict({
  "httpRequest" : {
    "method" : "POST",
    "headers" : {
      "Content-Type" : [ "application/x-www-form-urlencoded" ]
    },
    "body" : {
      "type" : "PARAMETERS",
      "parameters" : {
        "email" : [ "joe.blogs@gmail.com" ],
        "password" : [ "secure_Password123" ]
      }
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}))
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.upsert(MockServer::Expectation.from_hash({
  "httpRequest" : {
    "method" : "POST",
    "headers" : {
      "Content-Type" : [ "application/x-www-form-urlencoded" ]
    },
    "body" : {
      "type" : "PARAMETERS",
      "parameters" : {
        "email" : [ "joe.blogs@gmail.com" ],
        "password" : [ "secure_Password123" ]
      }
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}))
package main

import (
    "bytes"
    "net/http"
)

func main() {
    body := []byte(`{
  "httpRequest" : {
    "method" : "POST",
    "headers" : {
      "Content-Type" : [ "application/x-www-form-urlencoded" ]
    },
    "body" : {
      "type" : "PARAMETERS",
      "parameters" : {
        "email" : [ "joe.blogs@gmail.com" ],
        "password" : [ "secure_Password123" ]
      }
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}`)
    req, _ := http.NewRequest("PUT",
        "http://localhost:1080/mockserver/expectation",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    http.DefaultClient.Do(req)
}
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
  ""httpRequest"" : {
    ""method"" : ""POST"",
    ""headers"" : {
      ""Content-Type"" : [ ""application/x-www-form-urlencoded"" ]
    },
    ""body"" : {
      ""type"" : ""PARAMETERS"",
      ""parameters"" : {
        ""email"" : [ ""joe.blogs@gmail.com"" ],
        ""password"" : [ ""secure_Password123"" ]
      }
    }
  },
  ""httpResponse"" : {
    ""body"" : ""some_response_body""
  }
}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
  "httpRequest" : {
    "method" : "POST",
    "headers" : {
      "Content-Type" : [ "application/x-www-form-urlencoded" ]
    },
    "body" : {
      "type" : "PARAMETERS",
      "parameters" : {
        "email" : [ "joe.blogs@gmail.com" ],
        "password" : [ "secure_Password123" ]
      }
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
$json = <<<'JSON'
{
  "httpRequest" : {
    "method" : "POST",
    "headers" : {
      "Content-Type" : [ "application/x-www-form-urlencoded" ]
    },
    "body" : {
      "type" : "PARAMETERS",
      "parameters" : {
        "email" : [ "joe.blogs@gmail.com" ],
        "password" : [ "secure_Password123" ]
      }
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}
JSON;

$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_POSTFIELDS     => $json,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json; charset=utf-8'],
    CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
curl_close($ch);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
  "httpRequest" : {
    "method" : "POST",
    "headers" : {
      "Content-Type" : [ "application/x-www-form-urlencoded" ]
    },
    "body" : {
      "type" : "PARAMETERS",
      "parameters" : {
        "email" : [ "joe.blogs@gmail.com" ],
        "password" : [ "secure_Password123" ]
      }
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}'

See REST API for full JSON specification

Matches multipart/form-data uploads (e.g. file upload forms) by field value, filename, and/or part content-type. Matching is a sub-set — extra parts in the actual request are ignored. Values support Java regex and the ! prefix for negation, matching the same rules as form parameters.

The matcher fields are:

  • fields — map of field name to list of expected values (regex-capable)
  • filenames (optional) — map of field name to list of expected filename patterns (regex-capable)
  • partContentTypes (optional) — map of field name to list of expected part content-type patterns
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "method": "POST",
        "path": "/upload",
        "body": {
            "type": "MULTIPART",
            "fields": {
                "description": ["monthly report"],
                "file": [".*"]
            },
            "filenames": {
                "file": ["report.*\\.pdf"]
            },
            "partContentTypes": {
                "file": ["application/pdf"]
            }
        }
    },
    "httpResponse": {
        "statusCode": 201,
        "body": "upload accepted"
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import Expectation

client = MockServerClient("localhost", 1080)
client.upsert(Expectation.from_dict({
  "httpRequest" : {
    "method" : "POST",
    "path" : "/upload",
    "body" : {
      "type" : "MULTIPART",
      "fields" : {
        "description" : [ "monthly report" ],
        "file" : [ ".*" ]
      },
      "filenames" : {
        "file" : [ "report.*\\.pdf" ]
      },
      "partContentTypes" : {
        "file" : [ "application/pdf" ]
      }
    }
  },
  "httpResponse" : {
    "statusCode" : 201,
    "body" : "upload accepted"
  }
}))
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.upsert(MockServer::Expectation.from_hash({
  "httpRequest" : {
    "method" : "POST",
    "path" : "/upload",
    "body" : {
      "type" : "MULTIPART",
      "fields" : {
        "description" : [ "monthly report" ],
        "file" : [ ".*" ]
      },
      "filenames" : {
        "file" : [ "report.*\\.pdf" ]
      },
      "partContentTypes" : {
        "file" : [ "application/pdf" ]
      }
    }
  },
  "httpResponse" : {
    "statusCode" : 201,
    "body" : "upload accepted"
  }
}))
package main

import (
    "bytes"
    "net/http"
)

func main() {
    body := []byte(`{
  "httpRequest" : {
    "method" : "POST",
    "path" : "/upload",
    "body" : {
      "type" : "MULTIPART",
      "fields" : {
        "description" : [ "monthly report" ],
        "file" : [ ".*" ]
      },
      "filenames" : {
        "file" : [ "report.*\\.pdf" ]
      },
      "partContentTypes" : {
        "file" : [ "application/pdf" ]
      }
    }
  },
  "httpResponse" : {
    "statusCode" : 201,
    "body" : "upload accepted"
  }
}`)
    req, _ := http.NewRequest("PUT",
        "http://localhost:1080/mockserver/expectation",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    http.DefaultClient.Do(req)
}
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
  ""httpRequest"" : {
    ""method"" : ""POST"",
    ""path"" : ""/upload"",
    ""body"" : {
      ""type"" : ""MULTIPART"",
      ""fields"" : {
        ""description"" : [ ""monthly report"" ],
        ""file"" : [ "".*"" ]
      },
      ""filenames"" : {
        ""file"" : [ ""report.*\\.pdf"" ]
      },
      ""partContentTypes"" : {
        ""file"" : [ ""application/pdf"" ]
      }
    }
  },
  ""httpResponse"" : {
    ""statusCode"" : 201,
    ""body"" : ""upload accepted""
  }
}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
  "httpRequest" : {
    "method" : "POST",
    "path" : "/upload",
    "body" : {
      "type" : "MULTIPART",
      "fields" : {
        "description" : [ "monthly report" ],
        "file" : [ ".*" ]
      },
      "filenames" : {
        "file" : [ "report.*\\.pdf" ]
      },
      "partContentTypes" : {
        "file" : [ "application/pdf" ]
      }
    }
  },
  "httpResponse" : {
    "statusCode" : 201,
    "body" : "upload accepted"
  }
}"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
$json = <<<'JSON'
{
  "httpRequest" : {
    "method" : "POST",
    "path" : "/upload",
    "body" : {
      "type" : "MULTIPART",
      "fields" : {
        "description" : [ "monthly report" ],
        "file" : [ ".*" ]
      },
      "filenames" : {
        "file" : [ "report.*\\.pdf" ]
      },
      "partContentTypes" : {
        "file" : [ "application/pdf" ]
      }
    }
  },
  "httpResponse" : {
    "statusCode" : 201,
    "body" : "upload accepted"
  }
}
JSON;

$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_POSTFIELDS     => $json,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json; charset=utf-8'],
    CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
curl_close($ch);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
  "httpRequest" : {
    "method" : "POST",
    "path" : "/upload",
    "body" : {
      "type" : "MULTIPART",
      "fields" : {
        "description" : [ "monthly report" ],
        "file" : [ ".*" ]
      },
      "filenames" : {
        "file" : [ "report.*\\.pdf" ]
      },
      "partContentTypes" : {
        "file" : [ "application/pdf" ]
      }
    }
  },
  "httpResponse" : {
    "statusCode" : 201,
    "body" : "upload accepted"
  }
}'

See REST API for full JSON specification

Matches if at least one value is returned by the JsonPath expression

For a quick summary the XPath syntax please see w3schools, for details of the full XPath syntax please see www.w3.org

new MockServerClient("localhost", 1080)
    .when(
        request()
            // matches any request with an XML body that contains
            // one or more elements that match the XPath expression
            .withBody(
                xpath("/bookstore/book[price>30]/price")
            )
    )
    .respond(
        response()
            .withBody("some_response_body")
    );

// matches a request with the following body:
/*
<?xml version="1.0" encoding="ISO-8859-1"?>
<bookstore>
  <book category="COOKING">
    <title lang="en">Everyday Italian</title>
    <author>Giada De Laurentiis</author>
    <year>2005</year>
    <price>30.00</price>
  </book>
  <book category="CHILDREN">
    <title lang="en">Harry Potter</title>
    <author>J K. Rowling</author>
    <year>2005</year>
    <price>29.99</price>
  </book>
  <book category="WEB">
    <title lang="en">Learning XML</title>
    <author>Erik T. Ray</author>
    <year>2003</year>
    <price>31.95</price>
  </book>
</bookstore>
 */
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "body": {
            // matches any request with an XML body that contains
            // one or more elements that match the XPath expression
            "type": "XPATH",
            "xpath": "/bookstore/book[price>30]/price"
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
});

// matches a request with the following body:
/*
<?xml version="1.0" encoding="ISO-8859-1"?>
<bookstore>
  <book category="COOKING">
    <title lang="en">Everyday Italian</title>
    <author>Giada De Laurentiis</author>
    <year>2005</year>
    <price>30.00</price>
  </book>
  <book category="CHILDREN">
    <title lang="en">Harry Potter</title>
    <author>J K. Rowling</author>
    <year>2005</year>
    <price>29.99</price>
  </book>
  <book category="WEB">
    <title lang="en">Learning XML</title>
    <author>Erik T. Ray</author>
    <year>2003</year>
    <price>31.95</price>
  </book>
</bookstore>
 */

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import Expectation

client = MockServerClient("localhost", 1080)
client.upsert(Expectation.from_dict({
  "httpRequest" : {
    "body" : {
      "type" : "XPATH",
      "xpath" : "/bookstore/book[price>30]/price"
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}))
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.upsert(MockServer::Expectation.from_hash({
  "httpRequest" : {
    "body" : {
      "type" : "XPATH",
      "xpath" : "/bookstore/book[price>30]/price"
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}))
package main

import (
    "bytes"
    "net/http"
)

func main() {
    body := []byte(`{
  "httpRequest" : {
    "body" : {
      "type" : "XPATH",
      "xpath" : "/bookstore/book[price>30]/price"
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}`)
    req, _ := http.NewRequest("PUT",
        "http://localhost:1080/mockserver/expectation",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    http.DefaultClient.Do(req)
}
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
  ""httpRequest"" : {
    ""body"" : {
      ""type"" : ""XPATH"",
      ""xpath"" : ""/bookstore/book[price>30]/price""
    }
  },
  ""httpResponse"" : {
    ""body"" : ""some_response_body""
  }
}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
  "httpRequest" : {
    "body" : {
      "type" : "XPATH",
      "xpath" : "/bookstore/book[price>30]/price"
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
$json = <<<'JSON'
{
  "httpRequest" : {
    "body" : {
      "type" : "XPATH",
      "xpath" : "/bookstore/book[price>30]/price"
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}
JSON;

$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_POSTFIELDS     => $json,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json; charset=utf-8'],
    CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
curl_close($ch);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
  "httpRequest" : {
    "body" : {
      "type" : "XPATH",
      "xpath" : "/bookstore/book[price>30]/price"
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}'

See REST API for full JSON specification

Matches if at least one value is returned by the JsonPath expression

For a quick summary the XPath syntax please see w3schools, for details of the full XPath syntax please see www.w3.org

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withBody(
                // matches any request with an XML body that does NOT
                // contain one or more elements that match the XPath expression
                not(xpath("/bookstore/book[price>30]/price"))
            )
    )
    .respond(
        response()
            .withBody("some_response_body")
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "body": {
            // matches any request with an XML body that does NOT
            // contain one or more elements that match the XPath expression
            "not": true,
            "type": "XPATH",
            "xpath": "/bookstore/book[price>30]/price"
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import Expectation

client = MockServerClient("localhost", 1080)
client.upsert(Expectation.from_dict({
  "httpRequest" : {
    "body" : {
      "not" : True,
      "type" : "XPATH",
      "xpath" : "/bookstore/book[price>30]/price"
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}))
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.upsert(MockServer::Expectation.from_hash({
  "httpRequest" : {
    "body" : {
      "not" : true,
      "type" : "XPATH",
      "xpath" : "/bookstore/book[price>30]/price"
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}))
package main

import (
    "bytes"
    "net/http"
)

func main() {
    body := []byte(`{
  "httpRequest" : {
    "body" : {
      "not" : true,
      "type" : "XPATH",
      "xpath" : "/bookstore/book[price>30]/price"
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}`)
    req, _ := http.NewRequest("PUT",
        "http://localhost:1080/mockserver/expectation",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    http.DefaultClient.Do(req)
}
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
  ""httpRequest"" : {
    ""body"" : {
      ""not"" : true,
      ""type"" : ""XPATH"",
      ""xpath"" : ""/bookstore/book[price>30]/price""
    }
  },
  ""httpResponse"" : {
    ""body"" : ""some_response_body""
  }
}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
  "httpRequest" : {
    "body" : {
      "not" : true,
      "type" : "XPATH",
      "xpath" : "/bookstore/book[price>30]/price"
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
$json = <<<'JSON'
{
  "httpRequest" : {
    "body" : {
      "not" : true,
      "type" : "XPATH",
      "xpath" : "/bookstore/book[price>30]/price"
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}
JSON;

$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_POSTFIELDS     => $json,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json; charset=utf-8'],
    CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
curl_close($ch);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
  "httpRequest" : {
    "body" : {
      "not" : true,
      "type" : "XPATH",
      "xpath" : "/bookstore/book[price>30]/price"
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}'

See REST API for full JSON specification

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withBody(
                xml("<bookstore>" + System.lineSeparator() +
                    "   <book nationality=\"ITALIAN\" category=\"COOKING\">" + System.lineSeparator() +
                    "       <title lang=\"en\">Everyday Italian</title>" + System.lineSeparator() +
                    "       <author>Giada De Laurentiis</author>" + System.lineSeparator() +
                    "       <year>2005</year>" + System.lineSeparator() +
                    "       <price>30.00</price>" + System.lineSeparator() +
                    "   </book>" + System.lineSeparator() +
                    "</bookstore>")
            )
    )
    .respond(
        response()
            .withBody("some_response_body")
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "body": {
            "type": "XML",
            "xml":  "<bookstore>\n" +
                    "   <book nationality=\"ITALIAN\" category=\"COOKING\">\n" +
                    "       <title lang=\"en\">Everyday Italian</title>\n" +
                    "       <author>Giada De Laurentiis</author>\n" +
                    "       <year>2005</year>\n" +
                    "       <price>30.00</price>\n" +
                    "   </book>\n" +
                    "</bookstore>"
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import Expectation

client = MockServerClient("localhost", 1080)
client.upsert(Expectation.from_dict({
  "httpRequest" : {
    "body" : {
      "type" : "XML",
      "xml" : "<bookstore> <book nationality=\"ITALIAN\" category=\"COOKING\"><title lang=\"en\">Everyday Italian</title><author>Giada De Laurentiis</author><year>2005</year><price>30.00</price></book> </bookstore>"
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}))
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.upsert(MockServer::Expectation.from_hash({
  "httpRequest" : {
    "body" : {
      "type" : "XML",
      "xml" : "<bookstore> <book nationality=\"ITALIAN\" category=\"COOKING\"><title lang=\"en\">Everyday Italian</title><author>Giada De Laurentiis</author><year>2005</year><price>30.00</price></book> </bookstore>"
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}))
package main

import (
    "bytes"
    "net/http"
)

func main() {
    body := []byte(`{
  "httpRequest" : {
    "body" : {
      "type" : "XML",
      "xml" : "<bookstore> <book nationality=\"ITALIAN\" category=\"COOKING\"><title lang=\"en\">Everyday Italian</title><author>Giada De Laurentiis</author><year>2005</year><price>30.00</price></book> </bookstore>"
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}`)
    req, _ := http.NewRequest("PUT",
        "http://localhost:1080/mockserver/expectation",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    http.DefaultClient.Do(req)
}
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
  "httpRequest" : {
    "body" : {
      "type" : "XML",
      "xml" : "<bookstore> <book nationality=\"ITALIAN\" category=\"COOKING\"><title lang=\"en\">Everyday Italian</title><author>Giada De Laurentiis</author><year>2005</year><price>30.00</price></book> </bookstore>"
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
  "httpRequest" : {
    "body" : {
      "type" : "XML",
      "xml" : "<bookstore> <book nationality=\"ITALIAN\" category=\"COOKING\"><title lang=\"en\">Everyday Italian</title><author>Giada De Laurentiis</author><year>2005</year><price>30.00</price></book> </bookstore>"
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
$json = <<<'JSON'
{
  "httpRequest" : {
    "body" : {
      "type" : "XML",
      "xml" : "<bookstore> <book nationality=\"ITALIAN\" category=\"COOKING\"><title lang=\"en\">Everyday Italian</title><author>Giada De Laurentiis</author><year>2005</year><price>30.00</price></book> </bookstore>"
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}
JSON;

$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_POSTFIELDS     => $json,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json; charset=utf-8'],
    CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
curl_close($ch);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
  "httpRequest" : {
    "body" : {
      "type" : "XML",
      "xml" : "<bookstore> <book nationality=\"ITALIAN\" category=\"COOKING\"><title lang=\"en\">Everyday Italian</title><author>Giada De Laurentiis</author><year>2005</year><price>30.00</price></book> </bookstore>"
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}'

See REST API for full JSON specification

See XMLUnit documentation for full details of supported placeholders.

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withBody(
                xml("<bookstore>" + System.lineSeparator() +
                    "   <book nationality=\"ITALIAN\" category=\"COOKING\">" + System.lineSeparator() +
                    "       <title lang=\"en\">Everyday Italian</title>" + System.lineSeparator() +
                    "       <author>${xmlunit.ignore}</author>" + System.lineSeparator() +
                    "       <year>${xmlunit.isNumber}</year>" + System.lineSeparator() +
                    "       <price>30.00</price>" + System.lineSeparator() +
                    "   </book>" + System.lineSeparator() +
                    "</bookstore>")
            )
    )
    .respond(
        response()
            .withBody("some_response_body")
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest" : {
        "body" : {
            "type" : "XML",
            "xml" : "<bookstore>\n" +
                "   <book nationality=\"ITALIAN\" category=\"COOKING\">\n" +
                "       <title lang=\"en\">Everyday Italian</title>\n" +
                "       <author>${xmlunit.ignore}</author>\n" +
                "       <year>${xmlunit.isNumber}</year>\n" +
                "       <price>30.00</price>\n" +
                "   </book>\n" +
                "</bookstore>"
        }
    },
    "httpResponse" : {
        "body" : "some_response_body"
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import Expectation

client = MockServerClient("localhost", 1080)
client.upsert(Expectation.from_dict({
    "httpRequest" : {
        "body" : {
            "type" : "XML",
            "xml" : "<bookstore>\n   <book nationality=\"ITALIAN\" category=\"COOKING\">\n       <title lang=\"en\">Everyday Italian</title>\n       <author>${xmlunit.ignore}</author>\n       <year>${xmlunit.isNumber}</year>\n       <price>30.00</price>\n   </book>\n</bookstore>"
        }
    },
    "httpResponse" : {
        "body" : "some_response_body"
    }
}))
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.upsert(MockServer::Expectation.from_hash({
    "httpRequest" : {
        "body" : {
            "type" : "XML",
            "xml" : "<bookstore>\n   <book nationality=\"ITALIAN\" category=\"COOKING\">\n       <title lang=\"en\">Everyday Italian</title>\n       <author>${xmlunit.ignore}</author>\n       <year>${xmlunit.isNumber}</year>\n       <price>30.00</price>\n   </book>\n</bookstore>"
        }
    },
    "httpResponse" : {
        "body" : "some_response_body"
    }
}))
package main

import (
    "bytes"
    "net/http"
)

func main() {
    body := []byte(`{
    "httpRequest" : {
        "body" : {
            "type" : "XML",
            "xml" : "<bookstore>\n   <book nationality=\"ITALIAN\" category=\"COOKING\">\n       <title lang=\"en\">Everyday Italian</title>\n       <author>${xmlunit.ignore}</author>\n       <year>${xmlunit.isNumber}</year>\n       <price>30.00</price>\n   </book>\n</bookstore>"
        }
    },
    "httpResponse" : {
        "body" : "some_response_body"
    }
}`)
    req, _ := http.NewRequest("PUT",
        "http://localhost:1080/mockserver/expectation",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    http.DefaultClient.Do(req)
}
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
    ""httpRequest"" : {
        ""body"" : {
            ""type"" : ""XML"",
            ""xml"" : ""<bookstore>\n   <book nationality=\""ITALIAN\"" category=\""COOKING\"">\n       <title lang=\""en\"">Everyday Italian</title>\n       <author>${xmlunit.ignore}</author>\n       <year>${xmlunit.isNumber}</year>\n       <price>30.00</price>\n   </book>\n</bookstore>""
        }
    },
    ""httpResponse"" : {
        ""body"" : ""some_response_body""
    }
}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
    "httpRequest" : {
        "body" : {
            "type" : "XML",
            "xml" : "<bookstore>\n   <book nationality=\"ITALIAN\" category=\"COOKING\">\n       <title lang=\"en\">Everyday Italian</title>\n       <author>${xmlunit.ignore}</author>\n       <year>${xmlunit.isNumber}</year>\n       <price>30.00</price>\n   </book>\n</bookstore>"
        }
    },
    "httpResponse" : {
        "body" : "some_response_body"
    }
}"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
$json = <<<'JSON'
{
    "httpRequest" : {
        "body" : {
            "type" : "XML",
            "xml" : "<bookstore>\n   <book nationality=\"ITALIAN\" category=\"COOKING\">\n       <title lang=\"en\">Everyday Italian</title>\n       <author>${xmlunit.ignore}</author>\n       <year>${xmlunit.isNumber}</year>\n       <price>30.00</price>\n   </book>\n</bookstore>"
        }
    },
    "httpResponse" : {
        "body" : "some_response_body"
    }
}
JSON;

$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_POSTFIELDS     => $json,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json; charset=utf-8'],
    CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
curl_close($ch);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest" : {
        "body" : {
            "type" : "XML",
            "xml" : "<bookstore>\n   <book nationality=\"ITALIAN\" category=\"COOKING\">\n       <title lang=\"en\">Everyday Italian</title>\n       <author>${xmlunit.ignore}</author>\n       <year>${xmlunit.isNumber}</year>\n       <price>30.00</price>\n   </book>\n</bookstore>"
        }
    },
    "httpResponse" : {
        "body" : "some_response_body"
    }
}'

See REST API for full JSON specification

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withBody(
                xmlSchema("<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + System.lineSeparator() +
                    "<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" elementFormDefault=\"qualified\" attributeFormDefault=\"unqualified\">" + System.lineSeparator() +
                    "    <!-- XML Schema Generated from XML Document on Wed Jun 28 2017 21:52:45 GMT+0100 (BST) -->" + System.lineSeparator() +
                    "    <!-- with XmlGrid.net Free Online Service http://xmlgrid.net -->" + System.lineSeparator() +
                    "    <xs:element name=\"notes\">" + System.lineSeparator() +
                    "        <xs:complexType>" + System.lineSeparator() +
                    "            <xs:sequence>" + System.lineSeparator() +
                    "                <xs:element name=\"note\" maxOccurs=\"unbounded\">" + System.lineSeparator() +
                    "                    <xs:complexType>" + System.lineSeparator() +
                    "                        <xs:sequence>" + System.lineSeparator() +
                    "                            <xs:element name=\"to\" minOccurs=\"1\" maxOccurs=\"1\" type=\"xs:string\"></xs:element>" + System.lineSeparator() +
                    "                            <xs:element name=\"from\" minOccurs=\"1\" maxOccurs=\"1\" type=\"xs:string\"></xs:element>" + System.lineSeparator() +
                    "                            <xs:element name=\"heading\" minOccurs=\"1\" maxOccurs=\"1\" type=\"xs:string\"></xs:element>" + System.lineSeparator() +
                    "                            <xs:element name=\"body\" minOccurs=\"1\" maxOccurs=\"1\" type=\"xs:string\"></xs:element>" + System.lineSeparator() +
                    "                        </xs:sequence>" + System.lineSeparator() +
                    "                    </xs:complexType>" + System.lineSeparator() +
                    "                </xs:element>" + System.lineSeparator() +
                    "            </xs:sequence>" + System.lineSeparator() +
                    "        </xs:complexType>" + System.lineSeparator() +
                    "    </xs:element>" + System.lineSeparator() +
                    "</xs:schema>")
            )
    )
    .respond(
        response()
            .withBody("some_response_body")
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "body": {
            "type": "XML_SCHEMA",
            "xmlSchema": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" elementFormDefault=\"qualified\" attributeFormDefault=\"unqualified\">\n" +
            "    <!-- XML Schema Generated from XML Document on Wed Jun 28 2017 21:52:45 GMT+0100 (BST) -->\n" +
            "    <!-- with XmlGrid.net Free Online Service http://xmlgrid.net -->\n" +
            "    <xs:element name=\"notes\">\n" +
            "        <xs:complexType>\n" +
            "            <xs:sequence>\n" +
            "                <xs:element name=\"note\" maxOccurs=\"unbounded\">\n" +
            "                    <xs:complexType>\n" +
            "                        <xs:sequence>\n" +
            "                            <xs:element name=\"to\" minOccurs=\"1\" maxOccurs=\"1\" type=\"xs:string\"></xs:element>\n" +
            "                            <xs:element name=\"from\" minOccurs=\"1\" maxOccurs=\"1\" type=\"xs:string\"></xs:element>\n" +
            "                            <xs:element name=\"heading\" minOccurs=\"1\" maxOccurs=\"1\" type=\"xs:string\"></xs:element>\n" +
            "                            <xs:element name=\"body\" minOccurs=\"1\" maxOccurs=\"1\" type=\"xs:string\"></xs:element>\n" +
            "                        </xs:sequence>\n" +
            "                    </xs:complexType>\n" +
            "                </xs:element>\n" +
            "            </xs:sequence>\n" +
            "        </xs:complexType>\n" +
            "    </xs:element>\n</xs:schema>"
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import Expectation

client = MockServerClient("localhost", 1080)
client.upsert(Expectation.from_dict({
  "httpRequest" : {
    "body" : {
      "type" : "XML_SCHEMA",
      "xmlSchema" : "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" elementFormDefault=\"qualified\" attributeFormDefault=\"unqualified\"> <xs:element name=\"notes\"> <xs:complexType> <xs:sequence> <xs:element name=\"note\" maxOccurs=\"unbounded\"> <xs:complexType> <xs:sequence> <xs:element name=\"to\" minOccurs=\"1\" maxOccurs=\"1\" type=\"xs:string\"></xs:element> <xs:element name=\"from\" minOccurs=\"1\" maxOccurs=\"1\" type=\"xs:string\"></xs:element> <xs:element name=\"heading\" minOccurs=\"1\" maxOccurs=\"1\" type=\"xs:string\"></xs:element> <xs:element name=\"body\" minOccurs=\"1\" maxOccurs=\"1\" type=\"xs:string\"></xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:schema>"
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}))
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.upsert(MockServer::Expectation.from_hash({
  "httpRequest" : {
    "body" : {
      "type" : "XML_SCHEMA",
      "xmlSchema" : "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" elementFormDefault=\"qualified\" attributeFormDefault=\"unqualified\"> <xs:element name=\"notes\"> <xs:complexType> <xs:sequence> <xs:element name=\"note\" maxOccurs=\"unbounded\"> <xs:complexType> <xs:sequence> <xs:element name=\"to\" minOccurs=\"1\" maxOccurs=\"1\" type=\"xs:string\"></xs:element> <xs:element name=\"from\" minOccurs=\"1\" maxOccurs=\"1\" type=\"xs:string\"></xs:element> <xs:element name=\"heading\" minOccurs=\"1\" maxOccurs=\"1\" type=\"xs:string\"></xs:element> <xs:element name=\"body\" minOccurs=\"1\" maxOccurs=\"1\" type=\"xs:string\"></xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:schema>"
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}))
package main

import (
    "bytes"
    "net/http"
)

func main() {
    body := []byte(`{
  "httpRequest" : {
    "body" : {
      "type" : "XML_SCHEMA",
      "xmlSchema" : "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" elementFormDefault=\"qualified\" attributeFormDefault=\"unqualified\"> <xs:element name=\"notes\"> <xs:complexType> <xs:sequence> <xs:element name=\"note\" maxOccurs=\"unbounded\"> <xs:complexType> <xs:sequence> <xs:element name=\"to\" minOccurs=\"1\" maxOccurs=\"1\" type=\"xs:string\"></xs:element> <xs:element name=\"from\" minOccurs=\"1\" maxOccurs=\"1\" type=\"xs:string\"></xs:element> <xs:element name=\"heading\" minOccurs=\"1\" maxOccurs=\"1\" type=\"xs:string\"></xs:element> <xs:element name=\"body\" minOccurs=\"1\" maxOccurs=\"1\" type=\"xs:string\"></xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:schema>"
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}`)
    req, _ := http.NewRequest("PUT",
        "http://localhost:1080/mockserver/expectation",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    http.DefaultClient.Do(req)
}
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
  "httpRequest" : {
    "body" : {
      "type" : "XML_SCHEMA",
      "xmlSchema" : "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" elementFormDefault=\"qualified\" attributeFormDefault=\"unqualified\"> <xs:element name=\"notes\"> <xs:complexType> <xs:sequence> <xs:element name=\"note\" maxOccurs=\"unbounded\"> <xs:complexType> <xs:sequence> <xs:element name=\"to\" minOccurs=\"1\" maxOccurs=\"1\" type=\"xs:string\"></xs:element> <xs:element name=\"from\" minOccurs=\"1\" maxOccurs=\"1\" type=\"xs:string\"></xs:element> <xs:element name=\"heading\" minOccurs=\"1\" maxOccurs=\"1\" type=\"xs:string\"></xs:element> <xs:element name=\"body\" minOccurs=\"1\" maxOccurs=\"1\" type=\"xs:string\"></xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:schema>"
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
  "httpRequest" : {
    "body" : {
      "type" : "XML_SCHEMA",
      "xmlSchema" : "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" elementFormDefault=\"qualified\" attributeFormDefault=\"unqualified\"> <xs:element name=\"notes\"> <xs:complexType> <xs:sequence> <xs:element name=\"note\" maxOccurs=\"unbounded\"> <xs:complexType> <xs:sequence> <xs:element name=\"to\" minOccurs=\"1\" maxOccurs=\"1\" type=\"xs:string\"></xs:element> <xs:element name=\"from\" minOccurs=\"1\" maxOccurs=\"1\" type=\"xs:string\"></xs:element> <xs:element name=\"heading\" minOccurs=\"1\" maxOccurs=\"1\" type=\"xs:string\"></xs:element> <xs:element name=\"body\" minOccurs=\"1\" maxOccurs=\"1\" type=\"xs:string\"></xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:schema>"
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
$json = <<<'JSON'
{
  "httpRequest" : {
    "body" : {
      "type" : "XML_SCHEMA",
      "xmlSchema" : "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" elementFormDefault=\"qualified\" attributeFormDefault=\"unqualified\"> <xs:element name=\"notes\"> <xs:complexType> <xs:sequence> <xs:element name=\"note\" maxOccurs=\"unbounded\"> <xs:complexType> <xs:sequence> <xs:element name=\"to\" minOccurs=\"1\" maxOccurs=\"1\" type=\"xs:string\"></xs:element> <xs:element name=\"from\" minOccurs=\"1\" maxOccurs=\"1\" type=\"xs:string\"></xs:element> <xs:element name=\"heading\" minOccurs=\"1\" maxOccurs=\"1\" type=\"xs:string\"></xs:element> <xs:element name=\"body\" minOccurs=\"1\" maxOccurs=\"1\" type=\"xs:string\"></xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:schema>"
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}
JSON;

$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_POSTFIELDS     => $json,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json; charset=utf-8'],
    CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
curl_close($ch);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
  "httpRequest" : {
    "body" : {
      "type" : "XML_SCHEMA",
      "xmlSchema" : "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" elementFormDefault=\"qualified\" attributeFormDefault=\"unqualified\"> <xs:element name=\"notes\"> <xs:complexType> <xs:sequence> <xs:element name=\"note\" maxOccurs=\"unbounded\"> <xs:complexType> <xs:sequence> <xs:element name=\"to\" minOccurs=\"1\" maxOccurs=\"1\" type=\"xs:string\"></xs:element> <xs:element name=\"from\" minOccurs=\"1\" maxOccurs=\"1\" type=\"xs:string\"></xs:element> <xs:element name=\"heading\" minOccurs=\"1\" maxOccurs=\"1\" type=\"xs:string\"></xs:element> <xs:element name=\"body\" minOccurs=\"1\" maxOccurs=\"1\" type=\"xs:string\"></xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:schema>"
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}'

See REST API for full JSON specification

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withBody(
                xmlSchemaFromResource("org/mockserver/examples/mockserver/testXmlSchema.xsd")
            )
    )
    .respond(
        response()
            .withBody("some_response_body")
    );

JSON body matcher supports two mode STRICT which matches all fields, order of arrays and no additional fields allowed, and ONLY_MATCHING_FIELDS which only matches fields provided in the request matcher.

When matching JSON arrays the number of elements in the array must always match, however if ONLY_MATCHING_FIELDS mode is specified only the fields in the each array element in the matcher will be matched against each corresponding object in the array.

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withBody(
                json("{" + System.lineSeparator() +
                        "    \"id\": 1," + System.lineSeparator() +
                        "    \"name\": \"A green door\"," + System.lineSeparator() +
                        "    \"price\": 12.50," + System.lineSeparator() +
                        "    \"tags\": [\"home\", \"green\"]" + System.lineSeparator() +
                        "}",
                    MatchType.STRICT
                )
            )
    )
    .respond(
        response()
            .withStatusCode(HttpStatusCode.ACCEPTED_202.code())
            .withBody("some_response_body")
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "body": {
            "type": "JSON",
            "json": {
                "id": 1,
                "name": "A green door",
                "price": 12.50,
                "tags": ["home", "green"]
            },
            "matchType": "STRICT"
        }
    },
    "httpResponse": {
        "statusCode": 202,
        "body": "some_response_body"
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import Expectation

client = MockServerClient("localhost", 1080)
client.upsert(Expectation.from_dict({
    "httpRequest": {
        "body": {
            "type": "JSON",
            "json": {
                "id": 1,
                "name": "A green door",
                "price": 12.50,
                "tags": ["home", "green"]
            },
            "matchType": "STRICT"
        }
    },
    "httpResponse": {
        "statusCode": 202,
        "body": "some_response_body"
    }
}))
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.upsert(MockServer::Expectation.from_hash({
    "httpRequest": {
        "body": {
            "type": "JSON",
            "json": {
                "id": 1,
                "name": "A green door",
                "price": 12.50,
                "tags": ["home", "green"]
            },
            "matchType": "STRICT"
        }
    },
    "httpResponse": {
        "statusCode": 202,
        "body": "some_response_body"
    }
}))
package main

import (
    "bytes"
    "net/http"
)

func main() {
    body := []byte(`{
    "httpRequest": {
        "body": {
            "type": "JSON",
            "json": {
                "id": 1,
                "name": "A green door",
                "price": 12.50,
                "tags": ["home", "green"]
            },
            "matchType": "STRICT"
        }
    },
    "httpResponse": {
        "statusCode": 202,
        "body": "some_response_body"
    }
}`)
    req, _ := http.NewRequest("PUT",
        "http://localhost:1080/mockserver/expectation",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    http.DefaultClient.Do(req)
}
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
    ""httpRequest"": {
        ""body"": {
            ""type"": ""JSON"",
            ""json"": {
                ""id"": 1,
                ""name"": ""A green door"",
                ""price"": 12.50,
                ""tags"": [""home"", ""green""]
            },
            ""matchType"": ""STRICT""
        }
    },
    ""httpResponse"": {
        ""statusCode"": 202,
        ""body"": ""some_response_body""
    }
}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
    "httpRequest": {
        "body": {
            "type": "JSON",
            "json": {
                "id": 1,
                "name": "A green door",
                "price": 12.50,
                "tags": ["home", "green"]
            },
            "matchType": "STRICT"
        }
    },
    "httpResponse": {
        "statusCode": 202,
        "body": "some_response_body"
    }
}"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
$json = <<<'JSON'
{
    "httpRequest": {
        "body": {
            "type": "JSON",
            "json": {
                "id": 1,
                "name": "A green door",
                "price": 12.50,
                "tags": ["home", "green"]
            },
            "matchType": "STRICT"
        }
    },
    "httpResponse": {
        "statusCode": 202,
        "body": "some_response_body"
    }
}
JSON;

$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_POSTFIELDS     => $json,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json; charset=utf-8'],
    CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
curl_close($ch);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest": {
        "body": {
            "type": "JSON",
            "json": {
                "id": 1,
                "name": "A green door",
                "price": 12.50,
                "tags": ["home", "green"]
            },
            "matchType": "STRICT"
        }
    },
    "httpResponse": {
        "statusCode": 202,
        "body": "some_response_body"
    }
}'

See REST API for full JSON specification

JSON body matcher supports two mode STRICT which matches all fields, order of arrays and no additional fields allowed, and ONLY_MATCHING_FIELDS which only matches fields provided in the request matcher.

When matching JSON arrays the number of elements in the array must always match, however if ONLY_MATCHING_FIELDS mode is specified only the fields in the each array element in the matcher will be matched against each corresponding object in the array.

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withBody(
                json("{" + System.lineSeparator() +
                        "    \"id\": 1," + System.lineSeparator() +
                        "    \"name\": \"A green door\"," + System.lineSeparator() +
                        "    \"price\": 12.50," + System.lineSeparator() +
                        "    \"tags\": [\"home\", \"green\"]" + System.lineSeparator() +
                        "}",
                    MatchType.ONLY_MATCHING_FIELDS
                )
            )
    )
    .respond(
        response()
            .withStatusCode(HttpStatusCode.ACCEPTED_202.code())
            .withBody("some_response_body")
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "body": {
            "id": 1,
            "name": "A green door",
            "price": 12.50,
            "tags": ["home", "green"]
        }
    },
    "httpResponse": {
        "statusCode": 202,
        "body": "some_response_body"
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import Expectation

client = MockServerClient("localhost", 1080)
client.upsert(Expectation.from_dict({
    "httpRequest": {
        "body": {
            "id": 1,
            "name": "A green door",
            "price": 12.50,
            "tags": ["home", "green"]
        }
    },
    "httpResponse": {
        "statusCode": 202,
        "body": "some_response_body"
    }
}))
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.upsert(MockServer::Expectation.from_hash({
    "httpRequest": {
        "body": {
            "id": 1,
            "name": "A green door",
            "price": 12.50,
            "tags": ["home", "green"]
        }
    },
    "httpResponse": {
        "statusCode": 202,
        "body": "some_response_body"
    }
}))
package main

import (
    "bytes"
    "net/http"
)

func main() {
    body := []byte(`{
    "httpRequest": {
        "body": {
            "id": 1,
            "name": "A green door",
            "price": 12.50,
            "tags": ["home", "green"]
        }
    },
    "httpResponse": {
        "statusCode": 202,
        "body": "some_response_body"
    }
}`)
    req, _ := http.NewRequest("PUT",
        "http://localhost:1080/mockserver/expectation",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    http.DefaultClient.Do(req)
}
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
    ""httpRequest"": {
        ""body"": {
            ""id"": 1,
            ""name"": ""A green door"",
            ""price"": 12.50,
            ""tags"": [""home"", ""green""]
        }
    },
    ""httpResponse"": {
        ""statusCode"": 202,
        ""body"": ""some_response_body""
    }
}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
    "httpRequest": {
        "body": {
            "id": 1,
            "name": "A green door",
            "price": 12.50,
            "tags": ["home", "green"]
        }
    },
    "httpResponse": {
        "statusCode": 202,
        "body": "some_response_body"
    }
}"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
$json = <<<'JSON'
{
    "httpRequest": {
        "body": {
            "id": 1,
            "name": "A green door",
            "price": 12.50,
            "tags": ["home", "green"]
        }
    },
    "httpResponse": {
        "statusCode": 202,
        "body": "some_response_body"
    }
}
JSON;

$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_POSTFIELDS     => $json,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json; charset=utf-8'],
    CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
curl_close($ch);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest": {
        "body": {
            "id": 1,
            "name": "A green door",
            "price": 12.50,
            "tags": ["home", "green"]
        }
    },
    "httpResponse": {
        "statusCode": 202,
        "body": "some_response_body"
    }
}'

See REST API for full JSON specification

JSON body matcher supports two mode STRICT which matches all fields, order of arrays and no additional fields allowed, and ONLY_MATCHING_FIELDS which only matches fields provided in the request matcher.

When matching JSON arrays the number of elements in the array must always match, however if ONLY_MATCHING_FIELDS mode is specified only the fields in the each array element in the matcher will be matched against each corresponding object in the array.

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withBody(
                json(
                    "{\"context\": [{\"source\": \"DECISION_REQUEST\"},{\"source\": \"DECISION_REQUEST\"},{\"source\": \"DECISION_REQUEST\"}]}",
                    MatchType.ONLY_MATCHING_FIELDS
                )
            )
    )
    .respond(
        response()
            .withStatusCode(HttpStatusCode.ACCEPTED_202.code())
            .withBody("some_response_body")
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "method": "POST",
        "path": "/json",
        "body": {
            "type": "JSON",
            "json": {
                "context": [
                    {
                        "source": "DECISION_REQUEST"
                    },
                    {
                        "source": "DECISION_REQUEST"
                    },
                    {
                        "source": "DECISION_REQUEST"
                    }
                ]
            },
            "matchType": "ONLY_MATCHING_FIELDS"
        }
    },
    "httpResponse": {
        "statusCode": 200,
        "body": "some response"
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import Expectation

client = MockServerClient("localhost", 1080)
client.upsert(Expectation.from_dict({
    "httpRequest": {
        "method": "POST",
        "path": "/json",
        "body": {
            "type": "JSON",
            "json": {
                "context": [
                    {
                        "source": "DECISION_REQUEST"
                    },
                    {
                        "source": "DECISION_REQUEST"
                    },
                    {
                        "source": "DECISION_REQUEST"
                    }
                ]
            },
            "matchType": "ONLY_MATCHING_FIELDS"
        }
    },
    "httpResponse": {
        "statusCode": 200,
        "body": "some response"
    }
}))
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.upsert(MockServer::Expectation.from_hash({
    "httpRequest": {
        "method": "POST",
        "path": "/json",
        "body": {
            "type": "JSON",
            "json": {
                "context": [
                    {
                        "source": "DECISION_REQUEST"
                    },
                    {
                        "source": "DECISION_REQUEST"
                    },
                    {
                        "source": "DECISION_REQUEST"
                    }
                ]
            },
            "matchType": "ONLY_MATCHING_FIELDS"
        }
    },
    "httpResponse": {
        "statusCode": 200,
        "body": "some response"
    }
}))
package main

import (
    "bytes"
    "net/http"
)

func main() {
    body := []byte(`{
    "httpRequest": {
        "method": "POST",
        "path": "/json",
        "body": {
            "type": "JSON",
            "json": {
                "context": [
                    {
                        "source": "DECISION_REQUEST"
                    },
                    {
                        "source": "DECISION_REQUEST"
                    },
                    {
                        "source": "DECISION_REQUEST"
                    }
                ]
            },
            "matchType": "ONLY_MATCHING_FIELDS"
        }
    },
    "httpResponse": {
        "statusCode": 200,
        "body": "some response"
    }
}`)
    req, _ := http.NewRequest("PUT",
        "http://localhost:1080/mockserver/expectation",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    http.DefaultClient.Do(req)
}
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
    ""httpRequest"": {
        ""method"": ""POST"",
        ""path"": ""/json"",
        ""body"": {
            ""type"": ""JSON"",
            ""json"": {
                ""context"": [
                    {
                        ""source"": ""DECISION_REQUEST""
                    },
                    {
                        ""source"": ""DECISION_REQUEST""
                    },
                    {
                        ""source"": ""DECISION_REQUEST""
                    }
                ]
            },
            ""matchType"": ""ONLY_MATCHING_FIELDS""
        }
    },
    ""httpResponse"": {
        ""statusCode"": 200,
        ""body"": ""some response""
    }
}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
    "httpRequest": {
        "method": "POST",
        "path": "/json",
        "body": {
            "type": "JSON",
            "json": {
                "context": [
                    {
                        "source": "DECISION_REQUEST"
                    },
                    {
                        "source": "DECISION_REQUEST"
                    },
                    {
                        "source": "DECISION_REQUEST"
                    }
                ]
            },
            "matchType": "ONLY_MATCHING_FIELDS"
        }
    },
    "httpResponse": {
        "statusCode": 200,
        "body": "some response"
    }
}"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
$json = <<<'JSON'
{
    "httpRequest": {
        "method": "POST",
        "path": "/json",
        "body": {
            "type": "JSON",
            "json": {
                "context": [
                    {
                        "source": "DECISION_REQUEST"
                    },
                    {
                        "source": "DECISION_REQUEST"
                    },
                    {
                        "source": "DECISION_REQUEST"
                    }
                ]
            },
            "matchType": "ONLY_MATCHING_FIELDS"
        }
    },
    "httpResponse": {
        "statusCode": 200,
        "body": "some response"
    }
}
JSON;

$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_POSTFIELDS     => $json,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json; charset=utf-8'],
    CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
curl_close($ch);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest": {
        "method": "POST",
        "path": "/json",
        "body": {
            "type": "JSON",
            "json": {
                "context": [
                    {
                        "source": "DECISION_REQUEST"
                    },
                    {
                        "source": "DECISION_REQUEST"
                    },
                    {
                        "source": "DECISION_REQUEST"
                    }
                ]
            },
            "matchType": "ONLY_MATCHING_FIELDS"
        }
    },
    "httpResponse": {
        "statusCode": 200,
        "body": "some response"
    }
}'

See REST API for full JSON specification

See JSONUnit documentation for full details of supported placeholders.

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withBody(
                json("{" + System.lineSeparator() +
                        "    \"id\": 1," + System.lineSeparator() +
                        "    \"name\": \"A green door\"," + System.lineSeparator() +
                        "    \"price\": \"${json-unit.ignore-element}\"," + System.lineSeparator() +
                        "    \"enabled\": \"${json-unit.any-boolean}\"," + System.lineSeparator() +
                        "    \"tags\": [\"home\", \"green\"]" + System.lineSeparator() +
                        "}",
                    MatchType.ONLY_MATCHING_FIELDS
                )
            )
    )
    .respond(
        response()
            .withStatusCode(HttpStatusCode.ACCEPTED_202.code())
            .withBody("some_response_body")
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest" : {
        "body" : {
            "type" : "JSON",
            "json" : {
                "id" : 1,
                "name" : "A green door",
                "price" : "${json-unit.ignore-element}",
                "enabled" : "${json-unit.any-boolean}",
                "tags" : [ "home", "green" ]
            }
        }
    },
    "httpResponse" : {
        "statusCode" : 202,
        "body" : "some_response_body"
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import Expectation

client = MockServerClient("localhost", 1080)
client.upsert(Expectation.from_dict({
    "httpRequest" : {
        "body" : {
            "type" : "JSON",
            "json" : {
                "id" : 1,
                "name" : "A green door",
                "price" : "${json-unit.ignore-element}",
                "enabled" : "${json-unit.any-boolean}",
                "tags" : [ "home", "green" ]
            }
        }
    },
    "httpResponse" : {
        "statusCode" : 202,
        "body" : "some_response_body"
    }
}))
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.upsert(MockServer::Expectation.from_hash({
    "httpRequest" : {
        "body" : {
            "type" : "JSON",
            "json" : {
                "id" : 1,
                "name" : "A green door",
                "price" : "${json-unit.ignore-element}",
                "enabled" : "${json-unit.any-boolean}",
                "tags" : [ "home", "green" ]
            }
        }
    },
    "httpResponse" : {
        "statusCode" : 202,
        "body" : "some_response_body"
    }
}))
package main

import (
    "bytes"
    "net/http"
)

func main() {
    body := []byte(`{
    "httpRequest" : {
        "body" : {
            "type" : "JSON",
            "json" : {
                "id" : 1,
                "name" : "A green door",
                "price" : "${json-unit.ignore-element}",
                "enabled" : "${json-unit.any-boolean}",
                "tags" : [ "home", "green" ]
            }
        }
    },
    "httpResponse" : {
        "statusCode" : 202,
        "body" : "some_response_body"
    }
}`)
    req, _ := http.NewRequest("PUT",
        "http://localhost:1080/mockserver/expectation",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    http.DefaultClient.Do(req)
}
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
    ""httpRequest"" : {
        ""body"" : {
            ""type"" : ""JSON"",
            ""json"" : {
                ""id"" : 1,
                ""name"" : ""A green door"",
                ""price"" : ""${json-unit.ignore-element}"",
                ""enabled"" : ""${json-unit.any-boolean}"",
                ""tags"" : [ ""home"", ""green"" ]
            }
        }
    },
    ""httpResponse"" : {
        ""statusCode"" : 202,
        ""body"" : ""some_response_body""
    }
}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
    "httpRequest" : {
        "body" : {
            "type" : "JSON",
            "json" : {
                "id" : 1,
                "name" : "A green door",
                "price" : "${json-unit.ignore-element}",
                "enabled" : "${json-unit.any-boolean}",
                "tags" : [ "home", "green" ]
            }
        }
    },
    "httpResponse" : {
        "statusCode" : 202,
        "body" : "some_response_body"
    }
}"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
$json = <<<'JSON'
{
    "httpRequest" : {
        "body" : {
            "type" : "JSON",
            "json" : {
                "id" : 1,
                "name" : "A green door",
                "price" : "${json-unit.ignore-element}",
                "enabled" : "${json-unit.any-boolean}",
                "tags" : [ "home", "green" ]
            }
        }
    },
    "httpResponse" : {
        "statusCode" : 202,
        "body" : "some_response_body"
    }
}
JSON;

$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_POSTFIELDS     => $json,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json; charset=utf-8'],
    CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
curl_close($ch);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest" : {
        "body" : {
            "type" : "JSON",
            "json" : {
                "id" : 1,
                "name" : "A green door",
                "price" : "${json-unit.ignore-element}",
                "enabled" : "${json-unit.any-boolean}",
                "tags" : [ "home", "green" ]
            }
        }
    },
    "httpResponse" : {
        "statusCode" : 202,
        "body" : "some_response_body"
    }
}'

See REST API for full JSON specification

By default, JSON body matching treats 1 and 1.0 as different values because they have different numeric types (integer vs double). When matchNumbersAsStrings is set to true, numbers are compared by numeric value so 1, 1.0 and 1.00 are all considered equal. This is useful when different languages or serializers produce different numeric representations for the same value.

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withBody(
                json("{" + System.lineSeparator() +
                        "    \"id\": 1," + System.lineSeparator() +
                        "    \"price\": 12.5" + System.lineSeparator() +
                        "}",
                    MatchType.ONLY_MATCHING_FIELDS,
                    true // matchNumbersAsStrings
                )
            )
    )
    .respond(
        response()
            .withStatusCode(HttpStatusCode.ACCEPTED_202.code())
            .withBody("some_response_body")
    );

This expectation will match requests containing {"id": 1.0, "price": 12.50} as well as {"id": 1, "price": 12.5}.

from mockserver.client import MockServerClient
from mockserver.models import Expectation

client = MockServerClient("localhost", 1080)
client.upsert(Expectation.from_dict({
    "httpRequest": {
        "body": {
            "type": "JSON",
            "json": {
                "id": 1,
                "price": 12.5
            },
            "matchNumbersAsStrings": True
        }
    },
    "httpResponse": {
        "statusCode": 202,
        "body": "some_response_body"
    }
}))
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.upsert(MockServer::Expectation.from_hash({
    "httpRequest": {
        "body": {
            "type": "JSON",
            "json": {
                "id": 1,
                "price": 12.5
            },
            "matchNumbersAsStrings": true
        }
    },
    "httpResponse": {
        "statusCode": 202,
        "body": "some_response_body"
    }
}))
package main

import (
    "bytes"
    "net/http"
)

func main() {
    body := []byte(`{
    "httpRequest": {
        "body": {
            "type": "JSON",
            "json": {
                "id": 1,
                "price": 12.5
            },
            "matchNumbersAsStrings": true
        }
    },
    "httpResponse": {
        "statusCode": 202,
        "body": "some_response_body"
    }
}`)
    req, _ := http.NewRequest("PUT",
        "http://localhost:1080/mockserver/expectation",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    http.DefaultClient.Do(req)
}
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
    ""httpRequest"": {
        ""body"": {
            ""type"": ""JSON"",
            ""json"": {
                ""id"": 1,
                ""price"": 12.5
            },
            ""matchNumbersAsStrings"": true
        }
    },
    ""httpResponse"": {
        ""statusCode"": 202,
        ""body"": ""some_response_body""
    }
}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
    "httpRequest": {
        "body": {
            "type": "JSON",
            "json": {
                "id": 1,
                "price": 12.5
            },
            "matchNumbersAsStrings": true
        }
    },
    "httpResponse": {
        "statusCode": 202,
        "body": "some_response_body"
    }
}"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
$json = <<<'JSON'
{
    "httpRequest": {
        "body": {
            "type": "JSON",
            "json": {
                "id": 1,
                "price": 12.5
            },
            "matchNumbersAsStrings": true
        }
    },
    "httpResponse": {
        "statusCode": 202,
        "body": "some_response_body"
    }
}
JSON;

$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_POSTFIELDS     => $json,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json; charset=utf-8'],
    CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
curl_close($ch);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest": {
        "body": {
            "type": "JSON",
            "json": {
                "id": 1,
                "price": 12.5
            },
            "matchNumbersAsStrings": true
        }
    },
    "httpResponse": {
        "statusCode": 202,
        "body": "some_response_body"
    }
}'

See REST API for full JSON specification

For details of the full json schema supported please see json-schema.org.

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withBody(
                jsonSchema("{" + System.lineSeparator() +
                    "    \"$schema\": \"https://json-schema.org/draft-04/schema#\"," + System.lineSeparator() +
                    "    \"title\": \"Product\"," + System.lineSeparator() +
                    "    \"description\": \"A product from Acme catalog\"," + System.lineSeparator() +
                    "    \"type\": \"object\"," + System.lineSeparator() +
                    "    \"properties\": {" + System.lineSeparator() +
                    "        \"id\": {" + System.lineSeparator() +
                    "            \"description\": \"The unique identifier for a product\"," + System.lineSeparator() +
                    "            \"type\": \"integer\"" + System.lineSeparator() +
                    "        }," + System.lineSeparator() +
                    "        \"name\": {" + System.lineSeparator() +
                    "            \"description\": \"Name of the product\"," + System.lineSeparator() +
                    "            \"type\": \"string\"" + System.lineSeparator() +
                    "        }," + System.lineSeparator() +
                    "        \"price\": {" + System.lineSeparator() +
                    "            \"type\": \"number\"," + System.lineSeparator() +
                    "            \"minimum\": 0," + System.lineSeparator() +
                    "            \"exclusiveMinimum\": true" + System.lineSeparator() +
                    "        }," + System.lineSeparator() +
                    "        \"tags\": {" + System.lineSeparator() +
                    "            \"type\": \"array\"," + System.lineSeparator() +
                    "            \"items\": {" + System.lineSeparator() +
                    "                \"type\": \"string\"" + System.lineSeparator() +
                    "            }," + System.lineSeparator() +
                    "            \"minItems\": 1," + System.lineSeparator() +
                    "            \"uniqueItems\": true" + System.lineSeparator() +
                    "        }" + System.lineSeparator() +
                    "    }," + System.lineSeparator() +
                    "    \"required\": [\"id\", \"name\", \"price\"]" + System.lineSeparator() +
                    "}"))
    )
    .respond(
        response()
            .withBody("some_response_body")
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "body": {
            "type": "JSON_SCHEMA",
            "jsonSchema": {
                "$schema": "https://json-schema.org/draft-04/schema#",
                "title": "Product",
                "description": "A product from Acme catalog",
                "type": "object",
                "properties": {
                    "id": {
                        "description": "The unique identifier for a product",
                        "type": "integer"
                    },
                    "name": {
                        "description": "Name of the product",
                        "type": "string"
                    },
                    "price": {
                        "type": "number",
                        "minimum": 0,
                        "exclusiveMinimum": true
                    },
                    "tags": {
                        "type": "array",
                        "items": {
                            "type": "string"
                        },
                        "minItems": 1,
                        "uniqueItems": true
                    }
                },
                "required": [
                    "id",
                    "name",
                    "price"
                ]
            }
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import Expectation

client = MockServerClient("localhost", 1080)
client.upsert(Expectation.from_dict({
    "httpRequest": {
        "body": {
            "type": "JSON_SCHEMA",
            "jsonSchema": {
                "$schema": "https://json-schema.org/draft-04/schema#",
                "title": "Product",
                "description": "A product from Acme catalog",
                "type": "object",
                "properties": {
                    "id": {
                        "description": "The unique identifier for a product",
                        "type": "integer"
                    },
                    "name": {
                        "description": "Name of the product",
                        "type": "string"
                    },
                    "price": {
                        "type": "number",
                        "minimum": 0,
                        "exclusiveMinimum": True
                    },
                    "tags": {
                        "type": "array",
                        "items": {
                            "type": "string"
                        },
                        "minItems": 1,
                        "uniqueItems": True
                    }
                },
                "required": [
                    "id",
                    "name",
                    "price"
                ]
            }
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}))
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.upsert(MockServer::Expectation.from_hash({
    "httpRequest": {
        "body": {
            "type": "JSON_SCHEMA",
            "jsonSchema": {
                "$schema": "https://json-schema.org/draft-04/schema#",
                "title": "Product",
                "description": "A product from Acme catalog",
                "type": "object",
                "properties": {
                    "id": {
                        "description": "The unique identifier for a product",
                        "type": "integer"
                    },
                    "name": {
                        "description": "Name of the product",
                        "type": "string"
                    },
                    "price": {
                        "type": "number",
                        "minimum": 0,
                        "exclusiveMinimum": true
                    },
                    "tags": {
                        "type": "array",
                        "items": {
                            "type": "string"
                        },
                        "minItems": 1,
                        "uniqueItems": true
                    }
                },
                "required": [
                    "id",
                    "name",
                    "price"
                ]
            }
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}))
package main

import (
    "bytes"
    "net/http"
)

func main() {
    body := []byte(`{
    "httpRequest": {
        "body": {
            "type": "JSON_SCHEMA",
            "jsonSchema": {
                "$schema": "https://json-schema.org/draft-04/schema#",
                "title": "Product",
                "description": "A product from Acme catalog",
                "type": "object",
                "properties": {
                    "id": {
                        "description": "The unique identifier for a product",
                        "type": "integer"
                    },
                    "name": {
                        "description": "Name of the product",
                        "type": "string"
                    },
                    "price": {
                        "type": "number",
                        "minimum": 0,
                        "exclusiveMinimum": true
                    },
                    "tags": {
                        "type": "array",
                        "items": {
                            "type": "string"
                        },
                        "minItems": 1,
                        "uniqueItems": true
                    }
                },
                "required": [
                    "id",
                    "name",
                    "price"
                ]
            }
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}`)
    req, _ := http.NewRequest("PUT",
        "http://localhost:1080/mockserver/expectation",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    http.DefaultClient.Do(req)
}
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
    ""httpRequest"": {
        ""body"": {
            ""type"": ""JSON_SCHEMA"",
            ""jsonSchema"": {
                ""$schema"": ""https://json-schema.org/draft-04/schema#"",
                ""title"": ""Product"",
                ""description"": ""A product from Acme catalog"",
                ""type"": ""object"",
                ""properties"": {
                    ""id"": {
                        ""description"": ""The unique identifier for a product"",
                        ""type"": ""integer""
                    },
                    ""name"": {
                        ""description"": ""Name of the product"",
                        ""type"": ""string""
                    },
                    ""price"": {
                        ""type"": ""number"",
                        ""minimum"": 0,
                        ""exclusiveMinimum"": true
                    },
                    ""tags"": {
                        ""type"": ""array"",
                        ""items"": {
                            ""type"": ""string""
                        },
                        ""minItems"": 1,
                        ""uniqueItems"": true
                    }
                },
                ""required"": [
                    ""id"",
                    ""name"",
                    ""price""
                ]
            }
        }
    },
    ""httpResponse"": {
        ""body"": ""some_response_body""
    }
}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
    "httpRequest": {
        "body": {
            "type": "JSON_SCHEMA",
            "jsonSchema": {
                "$schema": "https://json-schema.org/draft-04/schema#",
                "title": "Product",
                "description": "A product from Acme catalog",
                "type": "object",
                "properties": {
                    "id": {
                        "description": "The unique identifier for a product",
                        "type": "integer"
                    },
                    "name": {
                        "description": "Name of the product",
                        "type": "string"
                    },
                    "price": {
                        "type": "number",
                        "minimum": 0,
                        "exclusiveMinimum": true
                    },
                    "tags": {
                        "type": "array",
                        "items": {
                            "type": "string"
                        },
                        "minItems": 1,
                        "uniqueItems": true
                    }
                },
                "required": [
                    "id",
                    "name",
                    "price"
                ]
            }
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
$json = <<<'JSON'
{
    "httpRequest": {
        "body": {
            "type": "JSON_SCHEMA",
            "jsonSchema": {
                "$schema": "https://json-schema.org/draft-04/schema#",
                "title": "Product",
                "description": "A product from Acme catalog",
                "type": "object",
                "properties": {
                    "id": {
                        "description": "The unique identifier for a product",
                        "type": "integer"
                    },
                    "name": {
                        "description": "Name of the product",
                        "type": "string"
                    },
                    "price": {
                        "type": "number",
                        "minimum": 0,
                        "exclusiveMinimum": true
                    },
                    "tags": {
                        "type": "array",
                        "items": {
                            "type": "string"
                        },
                        "minItems": 1,
                        "uniqueItems": true
                    }
                },
                "required": [
                    "id",
                    "name",
                    "price"
                ]
            }
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}
JSON;

$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_POSTFIELDS     => $json,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json; charset=utf-8'],
    CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
curl_close($ch);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest": {
        "body": {
            "type": "JSON_SCHEMA",
            "jsonSchema": {
                "$schema": "https://json-schema.org/draft-04/schema#",
                "title": "Product",
                "description": "A product from Acme catalog",
                "type": "object",
                "properties": {
                    "id": {
                        "description": "The unique identifier for a product",
                        "type": "integer"
                    },
                    "name": {
                        "description": "Name of the product",
                        "type": "string"
                    },
                    "price": {
                        "type": "number",
                        "minimum": 0,
                        "exclusiveMinimum": true
                    },
                    "tags": {
                        "type": "array",
                        "items": {
                            "type": "string"
                        },
                        "minItems": 1,
                        "uniqueItems": true
                    }
                },
                "required": [
                    "id",
                    "name",
                    "price"
                ]
            }
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}'

See REST API for full JSON specification

Matches if at least one value is returned by the JsonPath expression. For details of the full JsonPath supported please see github.com/json-path/JsonPath.

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withBody(
                // matches any request with an JSON body that contain
                // one or more fields that match the JsonPath expression
                jsonPath("$.store.book[?(@.price < 10)]")
            )
    )
    .respond(
        response()
            .withBody("some_response_body")
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "body": {
            // matches any request with an JSON body that contain
            // one or more fields that match the JsonPath expression
            "type": "JSON_PATH",
            "jsonPath": "$.store.book[?(@.price < 10)]"
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import Expectation

client = MockServerClient("localhost", 1080)
client.upsert(Expectation.from_dict({
  "httpRequest" : {
    "body" : {
      "type": "JSON_PATH",
      "jsonPath": "$.store.book[?(@.price < 10)]"
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}))
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.upsert(MockServer::Expectation.from_hash({
  "httpRequest" : {
    "body" : {
      "type": "JSON_PATH",
      "jsonPath": "$.store.book[?(@.price < 10)]"
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}))
package main

import (
    "bytes"
    "net/http"
)

func main() {
    body := []byte(`{
  "httpRequest" : {
    "body" : {
      "type": "JSON_PATH",
      "jsonPath": "$.store.book[?(@.price < 10)]"
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}`)
    req, _ := http.NewRequest("PUT",
        "http://localhost:1080/mockserver/expectation",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    http.DefaultClient.Do(req)
}
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
  ""httpRequest"" : {
    ""body"" : {
      ""type"": ""JSON_PATH"",
      ""jsonPath"": ""$.store.book[?(@.price < 10)]""
    }
  },
  ""httpResponse"" : {
    ""body"" : ""some_response_body""
  }
}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
  "httpRequest" : {
    "body" : {
      "type": "JSON_PATH",
      "jsonPath": "$.store.book[?(@.price < 10)]"
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
$json = <<<'JSON'
{
  "httpRequest" : {
    "body" : {
      "type": "JSON_PATH",
      "jsonPath": "$.store.book[?(@.price < 10)]"
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}
JSON;

$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_POSTFIELDS     => $json,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json; charset=utf-8'],
    CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
curl_close($ch);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
  "httpRequest" : {
    "body" : {
      "type": "JSON_PATH",
      "jsonPath": "$.store.book[?(@.price < 10)]"
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}'

See REST API for full JSON specification

Matches if at least one value is returned by the JsonPath expression. For details of the full JsonPath supported please see github.com/json-path/JsonPath.

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withBody(
                // matches any request with an JSON body that does NOT contain
                // one or more fields that match the JsonPath expression
                not(jsonPath("$.store.book[?(@.price < 10)]"))
            )
    )
    .respond(
        response()
            .withBody("some_response_body")
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "body": {
            // matches any request with an JSON body that does NOT contain
            // one or more fields that match the JsonPath expression
            "not": true,
            "type": "JSON_PATH",
            "jsonPath": "$.store.book[?(@.price < 10)]"
        }
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import Expectation

client = MockServerClient("localhost", 1080)
client.upsert(Expectation.from_dict({
  "httpRequest" : {
    "body" : {
      "not": True,
      "type": "JSON_PATH",
      "jsonPath": "$.store.book[?(@.price < 10)]"
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}))
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.upsert(MockServer::Expectation.from_hash({
  "httpRequest" : {
    "body" : {
      "not": true,
      "type": "JSON_PATH",
      "jsonPath": "$.store.book[?(@.price < 10)]"
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}))
package main

import (
    "bytes"
    "net/http"
)

func main() {
    body := []byte(`{
  "httpRequest" : {
    "body" : {
      "not": true,
      "type": "JSON_PATH",
      "jsonPath": "$.store.book[?(@.price < 10)]"
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}`)
    req, _ := http.NewRequest("PUT",
        "http://localhost:1080/mockserver/expectation",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    http.DefaultClient.Do(req)
}
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
  ""httpRequest"" : {
    ""body"" : {
      ""not"": true,
      ""type"": ""JSON_PATH"",
      ""jsonPath"": ""$.store.book[?(@.price < 10)]""
    }
  },
  ""httpResponse"" : {
    ""body"" : ""some_response_body""
  }
}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
  "httpRequest" : {
    "body" : {
      "not": true,
      "type": "JSON_PATH",
      "jsonPath": "$.store.book[?(@.price < 10)]"
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
$json = <<<'JSON'
{
  "httpRequest" : {
    "body" : {
      "not": true,
      "type": "JSON_PATH",
      "jsonPath": "$.store.book[?(@.price < 10)]"
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}
JSON;

$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_POSTFIELDS     => $json,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json; charset=utf-8'],
    CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
curl_close($ch);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
  "httpRequest" : {
    "body" : {
      "not": true,
      "type": "JSON_PATH",
      "jsonPath": "$.store.book[?(@.price < 10)]"
    }
  },
  "httpResponse" : {
    "body" : "some_response_body"
  }
}'

See REST API for full JSON specification

byte[] pngBytes = IOUtils.toByteArray(getClass().getClassLoader().getResourceAsStream("org/mockserver/examples/mockserver/test.png"));
new MockServerClient("localhost", 1080)
    .when(
        request()
            .withMethod("POST")
            .withHeaders(
                header("content-type", "image/png"),
                header("content-disposition", "form-data; name=\"test.png\"; filename=\"test.png\"")
            )
            .withBody(binary(pngBytes))
    )
    .respond(
        response()
            .withBody("png_saved_response")
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "method": "POST"
        "headers": {
            "content-type": ["image/png"],
            "content-disposition": ["form-data; name=\"test.png\"; filename=\"test.png\""]
        },
        "body": {
            "type": "BINARY",
            "base64Bytes": "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"
        }
    },
    "httpResponse" : {
        "body" : "png_saved_response"
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import Expectation

client = MockServerClient("localhost", 1080)
client.upsert(Expectation.from_dict({
    "httpRequest": {
        "method": "POST"
        "headers": {
            "content-type": ["image/png"],
            "content-disposition": ["form-data; name=\"test.png\"; filename=\"test.png\""]
        },
        "body": {
            "type": "BINARY",
            "base64Bytes": "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"
        }
    },
    "httpResponse" : {
        "body" : "png_saved_response"
    }
}))
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.upsert(MockServer::Expectation.from_hash({
    "httpRequest": {
        "method": "POST"
        "headers": {
            "content-type": ["image/png"],
            "content-disposition": ["form-data; name=\"test.png\"; filename=\"test.png\""]
        },
        "body": {
            "type": "BINARY",
            "base64Bytes": "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"
        }
    },
    "httpResponse" : {
        "body" : "png_saved_response"
    }
}))
package main

import (
    "bytes"
    "net/http"
)

func main() {
    body := []byte(`{
    "httpRequest": {
        "method": "POST"
        "headers": {
            "content-type": ["image/png"],
            "content-disposition": ["form-data; name=\"test.png\"; filename=\"test.png\""]
        },
        "body": {
            "type": "BINARY",
            "base64Bytes": "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"
        }
    },
    "httpResponse" : {
        "body" : "png_saved_response"
    }
}`)
    req, _ := http.NewRequest("PUT",
        "http://localhost:1080/mockserver/expectation",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    http.DefaultClient.Do(req)
}
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
    ""httpRequest"": {
        ""method"": ""POST""
        ""headers"": {
            ""content-type"": [""image/png""],
            ""content-disposition"": [""form-data; name=\""test.png\""; filename=\""test.png\""""]
        },
        ""body"": {
            ""type"": ""BINARY"",
            ""base64Bytes"": ""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""
        }
    },
    ""httpResponse"" : {
        ""body"" : ""png_saved_response""
    }
}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
    "httpRequest": {
        "method": "POST"
        "headers": {
            "content-type": ["image/png"],
            "content-disposition": ["form-data; name=\"test.png\"; filename=\"test.png\""]
        },
        "body": {
            "type": "BINARY",
            "base64Bytes": "iVBORw0KGgoAAAANSUhEUgAAAqwAAAApCAIAAAB/QuwlAAAK+GlDQ1BJQ0MgUHJvZmlsZQAASA2tl3dcU8kWx+fe9EYLICAl9CZIr9JrAAXpYCMkgYQSYgoCVpTFFVwLKiKgrugiiIJrAWQtiAULoljAvkEWFXVdLIiKypvAEvfzPm//e5PP3Pne35w598zcmXzOBYBGZQmFWagKANkCiSg6xJ+RmJTMIDwGWKAF8EAf2LHYYqFfVFQE+NfyoRcg8s5bNnJf/2r2vztUOVwxGwAkCnancsTsbMjHYH3PFookAGDqoG68RCKUcxdkdREMELJMzumT/F7OqROMJU7YxEYHAIDVBYBIZbFE6QBQLaDOyGWnQz/UUMh2Ag5fADkPsjebx+JAboU8Izs7R85/QLZI/Yef9H8wi5Wq8MlipSt4ci5wJHxwIF8szGLlT9z8Py/ZWVK4XhPFEF6pPFFoNGwT4ZpVZ+aEK1iQOidySufDGU0xTxoaN8VscQBcy8mxHFZg+BRLM+P8ppglgvS3DV/CjJ1iUU60wr8ga458f0zEwOMyFcwVB8VM6Wn8YOYUF/BiE6Y4lx8/Z4rFmTGKGAp4AQpdJI1WxJwmClbMMVsMR/79XDbr+7MkvFj5O56Ih8MNDJpiriBOEY9Q4q/wI8ya2N8T9tysEIUuzo1RjJWIYhV6BitMvl8n7IWSKMWagEDAB2IgBFmABfIBAyyB9xLAg5QGcoAIsAEXcOBdNAgB/rDNhioHagxgAYLgaCasDKjlQk0Ef/yJXksJNw/uWwACcoT5In46T8LwgyeNy2AK2LYzGA529k4wGHhu5TYAvLs7cR4RTeJ3bYcDAEFVcI9wvmtujwA4CM+AWu93zaQTANooAKffsaWi3El/WHmDA2SgDNSBNvxPMIbR2gAH4AI8gS+MOwxEgliQBBbC+fHgnERw3stAISgGpWAT2AYqwW6wF9SBQ+AIaAEnwVlwEVwFN8Ad8ADIwCB4CYbBBzCGIAgBoSF0RBsxQEwRa8QBcUO8kSAkAolGkpAUJB0RIFJkGbIGKUXKkEpkD1KP/IqcQM4il5Ee5B7Sjwwhb5HPKAalouqoHmqGzkTdUD80HI1FF6Dp6GK0AC1CN6AVaA16EG1Gz6JX0TuoDH2JjmAAhoLRxBhibDBumABMJCYZk4YRYVZgSjDlmBpMI6YN04m5hZFhXmE+YfFYOpaBtcF6YkOxcVg2djF2BXY9thJbh23GnsfewvZjh7HfcDScLs4a54Fj4hJx6bgluGJcOa4Wdxx3AXcHN4j7gMfjNfHmeFd8KD4Jn4Ffil+P34lvwrfje/AD+BECgaBNsCZ4ESIJLIKEUEzYQThIOEO4SRgkfCRSiAZEB2IwMZkoIK4mlhMPEE8TbxKfEcdIKiRTkgcpksQh5ZM2kvaR2kjXSYOkMbIq2ZzsRY4lZ5ALyRXkRvIF8kPyOwqFYkRxp8yl8CmrKBWUw5RLlH7KJ6oa1YoaQJ1PlVI3UPdT26n3qO9oNJoZzZeWTJPQNtDqaedoj2kflehKtkpMJY7SSqUqpWalm0qvlUnKpsp+yguVC5TLlY8qX1d+pUJSMVMJUGGprFCpUjmh0qcyokpXtVeNVM1WXa96QPWy6nM1gpqZWpAaR61Iba/aObUBOoZuTA+gs+lr6PvoF+iD6nh1c3WmeoZ6qfoh9W71YQ01DSeNeI08jSqNUxoyTYymmSZTM0tzo+YRzV7Nz9P0pvlN405bN61x2s1po1rTtXy1uFolWk1ad7Q+azO0g7QztTdrt2g/0sHqWOnM1Vmis0vngs6r6erTPaezp5dMPzL9vi6qa6UbrbtUd69ul+6Inr5eiJ5Qb4feOb1X+pr6vvoZ+lv1T+sPGdANvA34BlsNzhi8YGgw/BhZjArGecawoa5hqKHUcI9ht+GYkblRnNFqoyajR8ZkYzfjNOOtxh3GwyYGJrNNlpk0mNw3JZm6mfJMt5t2mo6amZslmK01azF7bq5lzjQvMG8wf2hBs/CxWGxRY3HbEm/pZplpudPyhhVq5WzFs6qyum6NWrtY8613WvfMwM1wnyGYUTOjz4Zq42eTa9Ng02+raRthu9q2xfb1TJOZyTM3z+yc+c3O2S7Lbp/dA3s1+zD71fZt9m8drBzYDlUOtx1pjsGOKx1bHd84WTtxnXY53XWmO892Xuvc4fzVxdVF5NLoMuRq4priWu3a56buFuW23u2SO87d332l+0n3Tx4uHhKPIx5/edp4Znoe8Hw+y3wWd9a+WQNeRl4srz1eMm+Gd4r3z94yH0Mflk+NzxNfY1+Ob63vMz9Lvwy/g36v/e38Rf7H/UcDPAKWB7QHYgJDAksCu4PUguKCKoMeBxsFpwc3BA+HOIcsDWkPxYWGh24O7WPqMdnMeuZwmGvY8rDz4dTwmPDK8CcRVhGiiLbZ6Oyw2VtmP5xjOkcwpyUSRDIjt0Q+ijKPWhz121z83Ki5VXOfRttHL4vujKHHLIo5EPMh1j92Y+yDOIs4aVxHvHL8/Pj6+NGEwISyBFnizMTliVeTdJL4Sa3JhOT45NrkkXlB87bNG5zvPL94fu8C8wV5Cy4v1FmYtfDUIuVFrEVHU3ApCSkHUr6wIlk1rJFUZmp16jA7gL2d/ZLjy9nKGeJ6ccu4z9K80srSnqd7pW9JH+L58Mp5r/gB/Er+m4zQjN0Zo5mRmfszx7MSspqyidkp2ScEaoJMwfkc/Zy8nB6htbBYKFvssXjb4mFRuKhWjIgXiFsl6jBB6pJaSH+Q9ud651blflwSv+RonmqeIK8r3yp/Xf6zguCCX5Zil7KXdiwzXFa4rH+53/I9K5AVqSs6VhqvLFo5uCpkVV0huTCz8Npqu9Vlq9+vSVjTVqRXtKpo4IeQHxqKlYpFxX1rPdfu/hH7I//H7nWO63as+1bCKblSaldaXvplPXv9lZ/sf6r4aXxD2obujS4bd23CbxJs6t3ss7muTLWsoGxgy+wtzVsZW0u2vt+2aNvlcqfy3dvJ26XbZRURFa07THZs2vGlkld5p8q/qqlat3pd9ehOzs6bu3x3Ne7W2126+/PP/J/v7gnZ01xjVlO+F783d+/TffH7On9x+6W+Vqe2tPbrfsF+WV103fl61/r6A7oHNjagDdKGoYPzD944FHiotdGmcU+TZlPpYXBYevjFrym/9h4JP9Jx1O1o4zHTY9XH6cdLmpHm/ObhFl6LrDWptedE2ImONs+247/Z/rb/pOHJqlMapzaeJp8uOj1+puDMSLuw/dXZ9LMDHYs6HpxLPHf7/Nzz3RfCL1y6GHzxXKdf55lLXpdOXva4fOKK25WWqy5Xm7ucu45fc752vNulu/m66/XWG+432npm9Zy+6XPz7K3AWxdvM29fvTPnTk9vXO/dvvl9srucu8/vZd17cz/3/tiDVQ9xD0seqTwqf6z7uOZ3y9+bZC6yU/2B/V1PYp48GGAPvPxD/MeXwaKntKflzwye1T93eH5yKHjoxot5LwZfCl+OvSr+U/XP6tcWr4/95ftX13Di8OAb0Zvxt+vfab/b/97pfcdI1MjjD9kfxkZLPmp/rPvk9qnzc8LnZ2NLvhC+VHy1/Nr2Lfzbw/Hs8XEhS8SayAUw8IqmpQHwdj/ME5IAoN8AgKw0mVdPWCCT3wKQkb+rXP4vnsy95R0whwCNsIn0BcC5HYCjsDWFLQ3WKMixvgB1dFRUMFnEaY4wn4EFobTA1KR8fPwdzCcJlgB87RsfH2sZH/9aC78R7gPQ/mEyn5cbqxwEwLfQwc454tropVVy5Z/lPzaRFDnqunSQAAABnGlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNS40LjAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczpleGlmPSJodHRwOi8vbnMuYWRvYmUuY29tL2V4aWYvMS4wLyI+CiAgICAgICAgIDxleGlmOlBpeGVsWERpbWVuc2lvbj42ODQ8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpQaXhlbFlEaW1lbnNpb24+NDE8L2V4aWY6UGl4ZWxZRGltZW5zaW9uPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4Kl/XR7QAAIpRJREFUeAHtfQ9YVNW69/Y4KChDgqKmGRl6JZMR8cN/ZQV0vqNZzWTW8djQjU6H8aknlXOPdbDsJlRe7JSiHR3/NZRgIqiMf0LNgQT/gFxABxUo0CECFBRsBprRGQ7fu9bae8+eYWbDIHnvp2s9PDNrr/W+73rXb71rrXevvd+hX2dnJ0MTRYAiQBGgCFAEKAL3HgK/u/e6THtMEaAIUAQoAhQBigBCgDoB1A4oAhQBigBFgCJwjyJAnYB7dOBptykCFAGKAEWAIkCdAGoDFAGKAEWAIkARuEcRoE7APTrwtNsUAYoARYAiQBGgTgC1AYoARYAiQBGgCNyjCFAn4B4deNptigBFgCJAEaAIUCeA2gBFgCJAEaAIUATuUQSoE3CPDjztNkWAIkARoAhQBKgTQG2AIkARoAhQBCgC9ygC1Am4RweedpsiQBGgCFAEKAISCgFFgCLwGyBgM9VVG41WhvHyChgx/H7/36AJKpIiQBH4/xUBS2tzi5mRDg+U/k9vwuInAabUmH5iSbHZZClHJFGbTS7HwlKuglogc1nrrrB3XO6kuSm32Swmk8VNpQfFYnIsdfFjN0x9+XibB/L6gFRMpe7E3w6vULa4HIdacRMSCu0+bypS+W2fAn/RFxttzuQ3ijJQld/2mNTbGnhLuRaEqNwKab9wQBsdsPv5aYeVjx1WTjvwTND2FxafPdvgrA+97msETOWbYb2J2Vze14Kd5d2xhpwbFlxX7kSL6+bSVkHZHc1W7cqYOnbDl2W3NZnuqMb/WxqzlabG+wQMHz16+KaSboavcmc8jLJqZyXoLsz3YVfEnQCG6X73tiISPzcqWa0/Qs3lm13WYzf0pLh3XKIiu1bqNy708/PZXNp9D7vyCkvE5Nhu1gJpnc2z7gul9yovplJ3Am+HVyhbXI5jragJCYX2IN/xKyEqrtBVOJFfP5XBemNtN52qPLy0omWv6WaHKzbrpT27lK9ca2GYgOgRC5cHKRYhR9+wsyQ2pOBUsysOWtbHCJhuwgHMnUh3rCGXnfn1Glpcf7lDfXWhgvkaWjxNVpfzwAU9LWIRsOgTY9dBXhYZFzLMRxwWq+kaEFy9htY1YV6cy6Na8ZMI6WvZnUqGIUSl6xVTl2ojUwpzl0y3t2EplcKF0V7gkJOGa1uaLIy3Z4ehveNyaLj7i0F+SHE4rO2eVJRCTI7vuK/PKE2MzxBRCX1eKaZSd43dDq9Qtrgcp1oxExIK7UG+P0dzQ3PYpAzFY0yKTNXfbGMrfTmi3n6jGeHL8G0JxFjOJcfC5ZC3v1O8Pp0leC/p7McLS7KLf/j0m/B9SwYLqGm2bxG43cncY23uWEMiGoW/qW36k8Xb37PFVUSgp1Vhb/zp4Pxb0gBq0R4i5z0IrUuR6pJclfgG7KHcXpJ3dxLAeQAg3msg0tyPcWX/oxlD6f74GMVkSP0mr0gtYE+IbA1HtqrVu4vZS0tD1vr4KEQEKSopNdf1bXjvuBACtsrcnaAGbiJKoVqxs6DGxV24rWFnUvzHX+uBYfHSvySlFhAaS0Pp+hUxUZOjIMXEr8mtFNy3udTcjRykCEm21mMZp3fnXELdt11L+3i/em/VhROF8S9ve3qmev7LGWl5VzlS9G1pMKhXps+fuW3+3G2Llx85XuXgWzWW/feK2K/mz/0qJnb/t2UNxXuPp3xRJlARS3KjUjOMjiIKjpX69ZusiEk6LOwar4Eb3j6GxU0rjDsTwuqJ6cDr75RpSarCwLPFzScrzztRoEvT2QMHY6LxE4QpGaqki1UOiN4o3qONmYJqo6fsSfi0us6lwVqqvkw6mLD44LrDVsZ6Cx9FBM/lPABoQxIYtvQ9p9lubSwtWBWTHh2d/kI0SK7i27U1FK1afPjLghuXcpFi0apj7/9Vm5B0uVlgyDdKj0FzyQfacYd6LOqv9a6eSzUUZakUk7FpTAazL6jl++h+NtkaUleoVmzOra3MTVIpYL7AfI7fzM16rJXTR0NpVjzMLUj9JkfFJOXW8K0AoaV0/3o0a0GQQrVmZy7f14aCVJVqRW5lTW5qEtuMIj63ll1OUBOW2p1JKsSnUMSv33+uWeyMx9ZauXMNzAOkBnCsWL+zspVFtQ8baijCOtfU5m6Gta6fKrUcQ+G2j6QXWWtUAA2an1Exa3YWCdBxy9hcckS9Vl1cbwHl41WqpNQi3BD7UbpzjUoVn1VOTpvdChGykLwISk7EzRUVOzadKWm6BeV1eScSV+pOnTfs/jhj/kz10zO3xa88ccnB3m6dPahbDEvf3G2w9KXsusiPMhJra83+bG/My1/BX+IXZVVVVV9+duTbMocFkG/dnS01FGxWxcTvF5gWKTlcwxmMpdYtziJV7u0TVHKnjLsqS20ubD5pUJ23cfmKNWDM3avN95zLmMqzYMRXbGZ3LlxsK0pNQiNeKbAdjr6b784eJ71aCbLkKSUOHOYSVNolRSbqrEBnLImEqsiUFsRTnywjdLLISFSMklKDqxxE9pKrs7MEa4jE2htglmkNjtI7O816OSLiUqTa2NnZUqLhrmWsmgyTmEN43WjuSo5DW6bLLzy0PnzOsVYoNV1WQp7926Scw+ZVWy4TltbSAr42mqNMPtJMaiu/2cPV8kIgs/WMidRzn65UqkhfxnYtUi7n+pagreZ4uG9XvH0PS9dWxE2om6HhlGe/jYVK6bYw1cnt8dvCpLs2FvLVjRkqKMlem5IdJt2mVJtxRWMGIkN/CsWuKJwJk+YcYpH5GbPg2qhUQhYWdqHB2mkuycJC2pAQo/7DKCwkSl8DdmQ8qcBy4tZcqqm/xTff2Wkzm2+Z0ZyA1FamYdsNC+MkS787io3NVLKLbYvo88S3z6FMVkYF4YVP0pdtS7NAvieioi45WUtnpz49jrONSM40ZDn1SE+x2WQscZhB/MxJyGF7yOuKM/W6RL4VbuYz6hIy9Vs0nAoMP/NkiQYsqCTFZTuROaTarOcsm9MAfzuvUUSZFn6lEqw/zLLqvm7ISedItGCK9REsiAcgkhsEGYukGCNpKKWkxViSgvsdV8Gjb60gMjOrwdLFhDgOFJps3HruAiUn4rINqbAobSpF84DkyRoV/dJWbrFKO8Ou72073uIWrhmb2NoZh34iCpt+SuBWPI4REb/wjx+dWoRLEVviAeG5HEpEcBapEkVPRBl3VdxgsRabXNLioCRWXVgi3Hb5vLk6nVh6CVnIgMusJwOHR5wHoEcZpkdUmIjXwIGFX8GVKRUtSKPqnGSkH9n4Sa0c7bJGvZqUN2F+a1MhUVpHroVCe8fV2UKcDHVhPRFWnYOXHrkGWu+SrIV4fUnOx8TWarKaLNPkY2JzoYYUKCvM4po7ynFqxnxZBcb90vdo7TVzTsBrBaTH59l9fev3cG29QqZBwleVeKG+eeYrsuunVQKoTReIW7BqD9LW2vLTupfIjEot67KsQ71D11p0ZNlNzCF7m7WE9Qnk+S78L0fe3wgWJw3FTUhUBye8wcqIE1Bbk4+30hXXWIqWfLQ3R12oLLQ7Aa26NLzdfneURaaW9QkUP4LX1qQj2/OBfRVIhrWpeGkYbMZp4FiwToDG1mku+zsq3BamrATnAKfWo4ncBg/lYVlLV5zM2H+p0mB3CKzVB3C7B3bk4ylsvrSD+CLKRrgmwrHMsjMVrU3G1u+xQEUK9jmgjSbcF2l+mbHTQ1FEQ/tnk45s/Msy2T6mx6ECeOQHu4HYbOKHTJ6sb0KdqMhMsM96ewMkZ0zHUz05n536hcRZT9BBdXUmnmiyZfkGNPNgWViGdVJqkEpkzQHJiVo9asaoT8C1KYXIdvMTsWnLEkrqodJarSN7YZcbFSCF/hTidUmpxh4O4FxNuNV61G4fNsSLUiZmVhjqjeZu+sj3AivS2VSiwV2UFxq7YSQNgRMAO2OiABZ7Z/HCK44wgkaQxFESEKLs+S1psFUTJ4Dk4XJ70S+ojtvXoz+6AFc1e/BqNmPPyVo0jNamHxNmoBVM9RVa0E5+hJ2GGdrzaDWzVR44DFXwp9xwGa4dk5gtCQBhmYQlIjiLVImiJ6KMSBUs4IXIt41MIaYoVJLoLSwheeLXCvItKdj2E7ntkx24SLWLRd0Rwa5X3T8OQHO7+yTTfb4kxN8bCIOfnoumfF7uZadjCSs+qcsrPl3eYLHBEen0jQa9TqcbxdjExHvAJZn5rlqdWaKaPooI9PG/D2WMLl9LlAzCTze8B6NnHKaKY+vgS6759LXZ+Cmy9/TXPtWggUo7/qOJEdPBQQ4wiCT86Gz49g2PB2KiRxfKkxbAsxVzxc/tbZWVR6AwYkriqxPwA+sBEa/K4yOgqOVktaUqp6yVYfwXPL5iPuqaxH/M0n9GB2Ehrj4cVKrUavLgDZTE/JVzgjGxJHzRag0aIW3ZZZDqlBx4fzNYHFrhNHBtQt3owDE7frf3fzBiwjQo21B1AVlhR92JHwwMMynm4eD7eGu7clADp4SShYee/j2LzIMvfzIJcekaDa31RzRAKVHsflYRAkVgr//nPxJhaCQ3yRk8nAMW5iXMKzlcwwS8EZW3Y8L97Hn/kN+vfFGTPnoaGjyGqblxfEPF6ldyF4Z+PeWFsxcQ4JaqY+gh0KT1c5Wz0YRhvMcq10yaBBntJcFJ5tQ9mrCIkCGB0iHTFUOg0qC5hOMdOuoKUV+YtyeGST0VBWzCVH5IA4/E4KZz7QK2j4tWJIHV+1mgjz2ZTbKcre+EBqJOhCj+BIwuZr2gvfKykoZWBPl01caSfJ1OPsrGmI6loZmnTvt0dhCaebAsfJqBzuTSsgv59UOWoFv5fChqRhr66pvIdnOLLjOW8i0fINPW7v8kfBRUSoKjlhD3Fwi6Jp9hM1NS1IWfq0aRgZL4DPdDVDetvEUAFH3QENt0XKZm5YKQoFFSb9E+8r3ISSQvsASGK5MTAEtpu+lGT8DBzY1SxCNYtu8qwp2xFexCd4oJi+dIe4YwqzPD9AQlnrhrJmKV4vVpGFbfMYnHZ8LbCq0nGm8wlu931QPxW1vlsx5EwygJHJeYOgUyxQcvtVnqvt5mhqfNSRnzHkVrX/8Jz/5hwxs+kBNJrmxJhBxmHWctXXFuPssaUteqng2BiDIuqyQ+XvjJ+sDbCA70n/cm8p4/yDguHPFly+YA5p4mpyeVnrLz9POC+cZtrl9XlU6MhBOqLUyaXIYeiMiVy+a+tPDlZ6L8RVXwhEs6e9GiAVnwTsDac3p9nh498idJtAWEoeHUCUSpjV2gyCYs6EqLsrBG9EwHPBY8s7tMxOhxeJPH9f2DYN5ntZz87+bZzM+opLgs9uUanvViMcresnbYsPv0nDzY3pHAh5+N0P0TE/D0XTJIJeLARE1+UFDrPTVayaSlXfnZyITzwyaoR9k7A4sQNNcmJD40Tkpzl20djHfwordLzmz48WDxrEejrny3G6qGvRjpzRj5JjvQo0xmaKgDMg/Mlp8/o21vMDK41jd4NCeTYcY890fykNJSigpbdtYexpXjZA+gXdqehoQ9N2fzcx0QgtpguFpZUndUW3tcB75FiXJJ4OkdTBE2tvNLsmKwhWG+Nvy+Qod9Q5IHsJsVOAmhkxQRJ+C9Ql11qDKE9GXI2wuHMky9p6LsOuIctivZvwn6GPR8dmcnoep+NslemRrISZQ8MFfOThmuiP+Whs+NY9K2pC2dm7YUdm35sgWKhYvkUbBkWMpLMQaLlQtyxnL0Rlwk8N0XzA3l6pgREeBdpeFLvM5Evjk7iK9kJkfOhYlrvxbkvINnx84bsFMdv7rk3GVtnn11END0SUNEnjx8AjtbLQbRPpLVcsbYAH5yS+Z8kt35Cdq3MnoADmkudN4rMiZNv25fxeo5oYz+y3XQP+WCp4J6iDCPQU9Q4om7ZqaF8wbBSIaPGAdLWuUVw7XmcrxS/fMvaXljOCaTEeVMHex8DBkf8aD9RVuZfDyzzeUQubclTrCbbxGcS5HXyfRiCMSUcWvzbvTztDg4en4ksy5vS5r+HwvCvSoy0YjLF0YKJkOPJfbRSYA8yG7D7tr2Dt1sbdJpkpX4uZc2bd1i+YwAr6iCZncMuLznXJbK+H5+M15avC4tLW/oUGVcQkpKAhKBHVPRNhgrFwoJhmnkklyplEfKhw2SwCrcG81dN9nhUIxX4cED+1u54xC4BWs3WcnfxKcCJob4BQxi54Z0yAABr6McQYXLbMjYAIdy3K6PL5xDiKU7CAsYsGsT6kYHd+pbGOnUF8Hdsu06eN3W/EM6rKYRIbAm2qz8WktYA4IckcF7v2Qwi0zAwyPdtYDKA/ARwpklR7JrCJm1sejUpvVF35bC8PT3lg55OHTCM689vW7fq/uzse+nvVTZ2sGwr0vB8mdrM5I/32ly34eifXx47do4i0CCH14YA5839hy3MM0VqC/Bj+B9sReiiJ7Cz9BgV33syWwaex+6rWOTZCCX6/odsmhzk16XvEwpgzq9dt0HsTPGBUStKYD7v0EstdE+8fzQzJNPHspjMXywvR2JF9eOZBDmxaZsb5KrtZewuZqseL9xMxZ/sE6rvT5UrkxITkH3246pTxpiRdrDFEX7KBk0DBgiHx1p7yKvkygjT0UygY/hs4AteRdNrcWHwERkCbHhSKYnQuDkqgcoObUsvIQ7FsElyUu8JP25+3qYzezi1i71i3jKb+KkwRJJfzQDpQM5GizA7g0L5OGse1viKXnDYRjeHERwFqnqDj0RZUSqeEUdM67UdqRwuPKPeBO996E9dLbVdC4nDbJxyqn4HNuBrAcXgoZ7QH07JJaG8lOVv4YsfGfHa+9oLK21F4u2J85drc37bG/5bJXd03dqoudcpotH0cFiZKI+Yzk5omQa9i+FOw/Y2LtLQ+9HtyFwGJj7SRRP21pTev4aEzJO2nMdeF63Gf6IE1Nca4JzMCYsNHBoPYye0V8ZvTdpIs97o8Zw8TozPti7/jvkLlcb2phJ3FLR1pjXzTEAK8Z6EzV54pRBFcqDbCk/gWzmviEO845lEHzdOVgEjTplxXVwIna49JVNfJI5c3zb6S98rrcwzLSYILhfh9NoLnXcRJtxY5GBedSOTGMRuvkaeJ8PqW06V8fM4m5uGnMPvrOB+cPfn0UPccADeFuh+7j/t+/teW/D1VVxVY/pJgQyHS1nK7a8zzDLJz4TDiPKJ68xTwRPY86dQQWDRyJjkyiyX/lPu7G1XyptvM6MCJYK9347+4T/C75KrWH3uW+ZetSX5ePv76UoXiZkiG2cKqtjZnN9bMiNf3M9o0hIlBX1ejYJm8B5U3lR8Y1BIe+s3fHOWk1rQ23Rge1zF6/Oe3dL+ZsfYgKZ7lhuFKcCHCGXFpxnRk3iAbzpEhTzL1eBGR47Wpbg55BI0tXLP2CBXT/YM/nETH3CglCy6h2O376a0QtJ+6IhoTyclxCH0k0fzT9cBqq83DrLEvxcBS5sBeuXf5brk7Dp3zG/G0ZcJ/iQzotNZNI+yM464GfOgvL4V2ehWvHWBfw42yOUnJkcru1384zp1yaoihgZ5EsKvT7f/8aT9lFuP3viZ+b+B3wtjXVAVtzSiqJu2VR98mcu6/Tt3paWzCakFvQrHsR2bPXnuPE1/+IW57Xz3FZ1MwQiyoQx59zY/JLZ/HIj7JtrtYUUznnvaGUys+XdrL3aMT6HoTL59ejebed9dBLgrJ+La8PRldHRM97dVQ51Em//4PA5r8IBIkrkoAZnu3x4wIVvESIjn2I9AMa0f/uXSJ7fQJEb3oFeaCMcPfkx+NSv1tiPJZoLYsdNfWLG1NNNtp7oQOSg5sRTpX7j0WuExFJTloIehjEBg353vwwdSremldl/Tqa56u2nD7z9xwPFTR0jHkVT58jb+RfYe0hL9qpjF4kU959EpTGTpgJJ2uIv+F9FMpXvTUY+gHz6WH933HcGlp6AJj407vTH5ZKHX14JmatfbQAfavQCeBbgkPwnhsP1jQ3//IlFlbFc2HsB7dPRDzzk7z8ZraFtWWlcWJ2t6uuPr57Xtd/irGnUg4Ph9wCe+dsjk4Cw+MRf0Q8IegfPwk8GPj26qUBo1u0XtFXYA5D6+QwJRcZmy9ZU82dgzQUHX3zqeNxTBoeoKaDi06hJsTBZis+/txz6ErTo90SJXoniZTJjpqA+arfvKGd9U1vu9o/gTvnyTS8ICIYqT2eTXbQwZzGsnBH9hOzdcuSBSfxHBc9R4RcI4K6wMwg9I2T0mm+KeI6CNbFTn3hi6hp7CV/lkJGOnCqDAu2OvWhJQclSvm7lapLt8uklRftC5FPRrAdgqtmvRieoTPdG6FlDXVqWiPZR+vAs9IaXvRe2hmP/uRQG4aKXb7BH4ATOUijBnVj9Siz0S5Y8LwTbu3jrzsreBkpY1NYVuXVgoCjd+nb9qVr4HjxQIhn2+DzIWb/JqEY1OJ36LOvPMUf/vLaG8R0aOhKKaj/fhZwBSG1VhX/7zEjyzp8itgTzDd/3p+86TVRoLU2bi4cYCRHBedi/9XIIRJQxubd54bpAuieitnP/Ha79Zz4Ps0e/LjZ2dR7DLHtxKlrPTbXlBQUFlQ3slHZgcHfR9V1BdyWCVxMFJCRYCL+Gypay4UPo7VYI9kP7PK61GjKJDvIEdU6OVp2IX0RmmHQUxOKYesVlrkgn8pWJ6nR46IAWCJIiU7R6PnaGb4mEYcgi5QmafIj6ykSLEaRI4E5Xk3eQ0TtTwCiuuaMcXjzOOEYHoEgB/Jew4XTGFi0bB/i3UqzbzX1sCM3W5C322uj3z+HalnX4ZVqICVz1j8MJbGgASEt1DhHEzTqq1MRFZspTMrVaDXmPmLwB7qitC97fBhYIP8OhGSz4guFmFRKakOjQdOmA8SQKEVTUkqAJsx7FAqA/BRsdR969V5AQwaZcNixQkb9vv35HIgkHQO//o0QCChBv/g7Nd3EkCkBKQgRR6IFCTV7Xt/20n40jwLGFbPweIlDmb9ec3LjmQByJIZRui0vHtm4uW0q0ivpue3rx9hWEPfXDHBs0y4YIcgpjVdAHF60AAZCNdmvulSheZif7jjFM0RSNJpGbMxAi2M1s6jpknUb8Ii2e9Xb5JGflJpdSnZmjzVTHkUC4uEzoh7maXRZkcYnpmekJrA4yLQ4CFL4mTWSRICPysnRTfiI7aZelZKancOq7jA4wp8MOCUmmhPmdnEAuUEFkXIq+xdp3DbGBBsIwRfE+thSmID1gDBJSNGp2ejLLcqC/4oxdddaRgAc4GE6v4AdBXAhPhjPdoORI7Do6IHzOnow9p1e9xMYB7qtFRm2uLiZLX/Rbh1Dta6R20yFc25R7iNS+8JZ23Uf2WOgXXEQHiNoSCUCDMV2WrE4hUSYIWBxAAeEhbnEWqRJFT0QZkSqAA2+L3Jv8ZlG1hduuME/Ggo1rgC4ns+HQJThsQMZdOg2Zy0sPQgQrcDyvUq13EGTGQa5CJ8BMQlTjUEyPQy0Ep7GTFo0MTolau7HaxfaOCwLP1OxOjmVHgq/BhRkndw2caCpUs0rIyM8YNGU6PiSUJ2RyXGKad5Fj7weEBQpDBIkToOSmB9j9C28VcJFlwPXLvvdR3C3/p3y/GP3AAEnWloz3UUAO/tuU8JEW/QLBjMMNXL3w21klY4XQJ4Jex6XoYHBcJmfezt8AFtjRhOA7DDdWSmhCqEBEB6dOGAvj0LbNOgGdnZX/hTbg1L/vR0sRJC66j+2+qSKX291JXF/2Rp09ls9sOInDArmQP0XxGRxQSnwLpYbH8Ocd6EcI+O258WgKCT7kGKEq7MDGHPCKudRU9qFCUCvd9WEWGwForsCOi+pnXjrLYyYxirvW2n/8ANf0QhSnBXybDWrWGyezQZ7ORtiKzqauQ8Y6AXjWC8STrLWpJJGc+rFTDna85AoOjhZ9pmOlPFPPzrwK/DMG6hKOlIs0VmrYVahCK1xSIhPw7s7XChWxNuU7rA7L1DptMlEnsbClDxsiooTbMKgh0keoNehS7PcsyBtIN3CjL8LI6cytUjCY7I2Qc/SviBAhRJAXR8mJ2EWI4IxU/jdO4I5le4Fdt9byYsEPpaAbmH3lXNBrZ2dD0WkVe5+zPvqlPaveQkGDybl2dr5pUVuycqHdeGDBq0pE3h5vPyI4i1SJoCeijEgVrEJILSUfuy6mttCchHkCCPeDAQz/8wB6HPrlcgrwGDpl+sE1mQl36NPSXHmxDv2omtegseNJUGEPWu4xl6W51nDd7OXlNxyCc9ATEktzg0ki9fd3GY1hMbWaGR+pj7eEfZhiAvYrRq9BfkMDRgTyTxqJgiI6dJHDdslSt/iR7OII2fHdT/paDIsfOVAcMeXk7sdNP11tMXcMCggYwz0G5CFoa75We9Us8fEJCPAL9B/AyTFeqPjF54ERDwcybW3/kvh6ezN1MWOzL4bIjuc8yT9I44WgTBeVmmsrrxitViszdOz4IKeuOXC64O1jWEhzXTR00sLpUkwHJ1IPL011lfDv/jqszOCHxg8d4vTQgGlvrG03M/19Bg25P1DwwLPbNizXq35sN6OzvwF+I4c8OMq7y/M6sNXrTcb+Pn6DA0ZIu7TbbQNCgtsUBc/p4R+aSXwGjR4VKFTTs9kkVMhVHiyw7jqa+oOGjg0JcnoUZaqtrIcjYD+/oSNGdZkVrqTxZTZTQ7XhOqwnIx4KFrdrsOzaGoPZ6uU3dPioQPR4AP6Tm8km8Q8UD1Fim/KkIV47YUa0j/CaFLzuIZEMChjd5f/KiTIKWxDL91xIT1G6sDX91U9a/rL39cVTBpN8/GGVMshyqbbNKhkwOmiYr9CYkG6WuqoWNMpS38BRfvxMa66pqzf7hEwaxrRB8PjvfH0HVG1NX8RJdtknEVsCowVL8vHxGz7K1bCK4CxSBafs7u1TRBmRKqd+daO2EzV3aanc6fPIK/ALxC25KqcZxZF0/33HnYDuVbpLKGyWW621F1RzTtSGyHQ5Tw5hnQCZbveT+LGxB91sK9M9OR/eARj+dekfH0VD3b57+TfJWWZm3uNFX0xxnmgeCKakFAGKAEWgFwh0WNraC1L2/X2bUegEkLyH4izqmVu3XmGeWK1Yu3AM8N44X7jgueJWhll5XKV4kLsR8lDoXU8O/wQXfmZj119Gx6Yx8JNBKwUv1nrad7qDeIpYT+nPb/v6z5+h9/4gWAyhbGPa4RMGzvPkOyX8jyMvZlxpejV8A8QNtn/fgt64YXw+XyGj4+c5nJSDIkARuD0E2i4vCs3BqxAzwIsckPVmZcNKeMs/Cd76ek1+QvbUFL+IEGvx92jZDHoj+lnqAbgfJf0W+dSl8D4gpMQ/34YHAPz9P/zwQySHpr5G4Nem5gvXrI9ETfxHyuMjwJ39180mQ2PgrPHR0xxOXHvWrM9jC4NH9G+t/clUfd78y0ivCEXIB5uenzWKe1O9Z1IoFUWAIkAR6AME/mWpvVDf+dB9yg/m/ft0dLLZdv264eqAxxSPBN/nyUMzrIp07PhnZvVvvXa95nx7g8HmHxEQ8x9PJakm0EMAkZH6ta7q+2teMx5//auchEektxXlRx8HiOBMqygCFAGKAEWAInA3I3BbHsTdDAztG0WAIkARoAhQBO52BKgTcLePMO0fRYAiQBGgCFAE3CBAnQA3wNBiigBFgCJAEaAI3O0IUCfgbh9h2j+KAEWAIkARoAi4QYA6AW6AocUUAYoARYAiQBG42xGgTsDdPsK0fxQBigBFgCJAEXCDAHUC3ABDiykCFAGKAEWAInC3I0CdgLt9hGn/KAIUAYoARYAi4AYB6gS4AYYWUwQoAhQBigBF4G5HgDoBd/sI0/5RBCgCFAGKAEXADQL/D4BaqFLDMQVOAAAAAElFTkSuQmCC"
        }
    },
    "httpResponse" : {
        "body" : "png_saved_response"
    }
}"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
$json = <<<'JSON'
{
    "httpRequest": {
        "method": "POST"
        "headers": {
            "content-type": ["image/png"],
            "content-disposition": ["form-data; name=\"test.png\"; filename=\"test.png\""]
        },
        "body": {
            "type": "BINARY",
            "base64Bytes": "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"
        }
    },
    "httpResponse" : {
        "body" : "png_saved_response"
    }
}
JSON;

$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_POSTFIELDS     => $json,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json; charset=utf-8'],
    CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
curl_close($ch);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest": {
        "method": "POST"
        "headers": {
            "content-type": ["image/png"],
            "content-disposition": ["form-data; name=\"test.png\"; filename=\"test.png\""]
        },
        "body": {
            "type": "BINARY",
            "base64Bytes": "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"
        }
    },
    "httpResponse" : {
        "body" : "png_saved_response"
    }
}'

See REST API for full JSON specification

new MockServerClient("localhost", 1080)
    .upsert(
        new Expectation(
            request().withPath("/some/path"),
            Times.once(),
            TimeToLive.exactly(TimeUnit.SECONDS, 60L),
            100
        )
        .withId("some_unique_id")
        .thenRespond(response().withBody("some_response_body"))
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "id": "some_unique_id",
    "httpRequest": {
        "path": "/some/path"
    },
    "httpResponse": {
        "body": "some_response_body"
    },
    "times": {
        "remainingTimes": 1,
        "unlimited": false
    },
    "timeToLive": {
        "timeUnit": "SECONDS",
        "timeToLive": 60,
        "unlimited": false
    },
    "priority" : 100
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import Expectation

client = MockServerClient("localhost", 1080)
client.upsert(Expectation.from_dict({
  "id": "some_unique_id",
  "httpRequest" : {
    "path" : "/some/path"
  },
  "httpResponse" : {
    "body" : "some_response_body"
  },
  "times" : {
    "remainingTimes" : 1,
    "unlimited" : False
  },
  "timeToLive" : {
    "timeUnit" : "SECONDS",
    "timeToLive" : 60,
    "unlimited" : False
  },
  "priority" : 100
}))
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.upsert(MockServer::Expectation.from_hash({
  "id": "some_unique_id",
  "httpRequest" : {
    "path" : "/some/path"
  },
  "httpResponse" : {
    "body" : "some_response_body"
  },
  "times" : {
    "remainingTimes" : 1,
    "unlimited" : false
  },
  "timeToLive" : {
    "timeUnit" : "SECONDS",
    "timeToLive" : 60,
    "unlimited" : false
  },
  "priority" : 100
}))
package main

import (
    "bytes"
    "net/http"
)

func main() {
    body := []byte(`{
  "id": "some_unique_id",
  "httpRequest" : {
    "path" : "/some/path"
  },
  "httpResponse" : {
    "body" : "some_response_body"
  },
  "times" : {
    "remainingTimes" : 1,
    "unlimited" : false
  },
  "timeToLive" : {
    "timeUnit" : "SECONDS",
    "timeToLive" : 60,
    "unlimited" : false
  },
  "priority" : 100
}`)
    req, _ := http.NewRequest("PUT",
        "http://localhost:1080/mockserver/expectation",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    http.DefaultClient.Do(req)
}
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
  ""id"": ""some_unique_id"",
  ""httpRequest"" : {
    ""path"" : ""/some/path""
  },
  ""httpResponse"" : {
    ""body"" : ""some_response_body""
  },
  ""times"" : {
    ""remainingTimes"" : 1,
    ""unlimited"" : false
  },
  ""timeToLive"" : {
    ""timeUnit"" : ""SECONDS"",
    ""timeToLive"" : 60,
    ""unlimited"" : false
  },
  ""priority"" : 100
}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
  "id": "some_unique_id",
  "httpRequest" : {
    "path" : "/some/path"
  },
  "httpResponse" : {
    "body" : "some_response_body"
  },
  "times" : {
    "remainingTimes" : 1,
    "unlimited" : false
  },
  "timeToLive" : {
    "timeUnit" : "SECONDS",
    "timeToLive" : 60,
    "unlimited" : false
  },
  "priority" : 100
}"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
$json = <<<'JSON'
{
  "id": "some_unique_id",
  "httpRequest" : {
    "path" : "/some/path"
  },
  "httpResponse" : {
    "body" : "some_response_body"
  },
  "times" : {
    "remainingTimes" : 1,
    "unlimited" : false
  },
  "timeToLive" : {
    "timeUnit" : "SECONDS",
    "timeToLive" : 60,
    "unlimited" : false
  },
  "priority" : 100
}
JSON;

$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_POSTFIELDS     => $json,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json; charset=utf-8'],
    CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
curl_close($ch);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
  "id": "some_unique_id",
  "httpRequest" : {
    "path" : "/some/path"
  },
  "httpResponse" : {
    "body" : "some_response_body"
  },
  "times" : {
    "remainingTimes" : 1,
    "unlimited" : false
  },
  "timeToLive" : {
    "timeUnit" : "SECONDS",
    "timeToLive" : 60,
    "unlimited" : false
  },
  "priority" : 100
}'

See REST API for full JSON specification

 

An open api request matcher can contain any of the following fields:

MockServer creates a set of request properties matchers for each open api request matcher, to ensures control-plane logic such as clearing expectations or retrieving expectations work consistently between the two types of request matchers, this can be viewed in the MockServer UI active expectations section.

The following code examples show how to match request using an Open API specification. For more examples see the code examples folder in the git repository.

For brevity static imports have not been included in the Java code examples so please add the following static imports if copying this code

import static org.mockserver.model.HttpRequest.request;
import static org.mockserver.model.HttpResponse.response;

new MockServerClient("localhost", 1080)
    .when(
        openAPI(
            "https://raw.githubusercontent.com/mock-server/mockserver-monorepo/master/mockserver/mockserver-integration-testing/src/main/resources/org/mockserver/openapi/openapi_petstore_example.json"
        )
    )
    .respond(
        response()
            .withBody("some_response_body")
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "specUrlOrPayload": "https://raw.githubusercontent.com/mock-server/mockserver-monorepo/master/mockserver/mockserver-integration-testing/src/main/resources/org/mockserver/openapi/openapi_petstore_example.json"
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import Expectation

client = MockServerClient("localhost", 1080)
client.upsert(Expectation.from_dict({
    "httpRequest": {
        "specUrlOrPayload": "https://raw.githubusercontent.com/mock-server/mockserver-monorepo/master/mockserver/mockserver-integration-testing/src/main/resources/org/mockserver/openapi/openapi_petstore_example.json"
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}))
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.upsert(MockServer::Expectation.from_hash({
    "httpRequest": {
        "specUrlOrPayload": "https://raw.githubusercontent.com/mock-server/mockserver-monorepo/master/mockserver/mockserver-integration-testing/src/main/resources/org/mockserver/openapi/openapi_petstore_example.json"
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}))
package main

import (
    "bytes"
    "net/http"
)

func main() {
    body := []byte(`{
    "httpRequest": {
        "specUrlOrPayload": "https://raw.githubusercontent.com/mock-server/mockserver-monorepo/master/mockserver/mockserver-integration-testing/src/main/resources/org/mockserver/openapi/openapi_petstore_example.json"
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}`)
    req, _ := http.NewRequest("PUT",
        "http://localhost:1080/mockserver/expectation",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    http.DefaultClient.Do(req)
}
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
    ""httpRequest"": {
        ""specUrlOrPayload"": ""https://raw.githubusercontent.com/mock-server/mockserver-monorepo/master/mockserver/mockserver-integration-testing/src/main/resources/org/mockserver/openapi/openapi_petstore_example.json""
    },
    ""httpResponse"": {
        ""body"": ""some_response_body""
    }
}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
    "httpRequest": {
        "specUrlOrPayload": "https://raw.githubusercontent.com/mock-server/mockserver-monorepo/master/mockserver/mockserver-integration-testing/src/main/resources/org/mockserver/openapi/openapi_petstore_example.json"
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
// OpenAPI matchers are not supported in the PHP client;
// use the REST API directly
$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'PUT',
    CURLOPT_POSTFIELDS => json_encode([[
        'httpRequest' => [
            'specUrlOrPayload' => 'https://raw.githubusercontent.com/mock-server/mockserver-monorepo/master/mockserver/mockserver-integration-testing/src/main/resources/org/mockserver/openapi/openapi_petstore_example.json',
        ],
        'httpResponse' => ['body' => 'some_response_body'],
    ]]),
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => ['Content-Type: application/json; charset=utf-8'],
]);
curl_exec($ch);
curl_close($ch);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest": {
        "specUrlOrPayload": "https://raw.githubusercontent.com/mock-server/mockserver-monorepo/master/mockserver/mockserver-integration-testing/src/main/resources/org/mockserver/openapi/openapi_petstore_example.json"
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}'

See REST API for full JSON specification

new MockServerClient("localhost", 1080)
    .when(
        openAPI(
            "https://raw.githubusercontent.com/mock-server/mockserver-monorepo/master/mockserver/mockserver-integration-testing/src/main/resources/org/mockserver/openapi/openapi_petstore_example.json",
            "showPetById"
        )
    )
    .respond(
        response()
            .withBody("some_response_body")
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "specUrlOrPayload": "https://raw.githubusercontent.com/mock-server/mockserver-monorepo/master/mockserver/mockserver-integration-testing/src/main/resources/org/mockserver/openapi/openapi_petstore_example.json",
        "operationId": "showPetById"
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import Expectation

client = MockServerClient("localhost", 1080)
client.upsert(Expectation.from_dict({
    "httpRequest": {
        "specUrlOrPayload": "https://raw.githubusercontent.com/mock-server/mockserver-monorepo/master/mockserver/mockserver-integration-testing/src/main/resources/org/mockserver/openapi/openapi_petstore_example.json",
        "operationId": "showPetById"
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}))
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.upsert(MockServer::Expectation.from_hash({
    "httpRequest": {
        "specUrlOrPayload": "https://raw.githubusercontent.com/mock-server/mockserver-monorepo/master/mockserver/mockserver-integration-testing/src/main/resources/org/mockserver/openapi/openapi_petstore_example.json",
        "operationId": "showPetById"
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}))
package main

import (
    "bytes"
    "net/http"
)

func main() {
    body := []byte(`{
    "httpRequest": {
        "specUrlOrPayload": "https://raw.githubusercontent.com/mock-server/mockserver-monorepo/master/mockserver/mockserver-integration-testing/src/main/resources/org/mockserver/openapi/openapi_petstore_example.json",
        "operationId": "showPetById"
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}`)
    req, _ := http.NewRequest("PUT",
        "http://localhost:1080/mockserver/expectation",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    http.DefaultClient.Do(req)
}
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
    ""httpRequest"": {
        ""specUrlOrPayload"": ""https://raw.githubusercontent.com/mock-server/mockserver-monorepo/master/mockserver/mockserver-integration-testing/src/main/resources/org/mockserver/openapi/openapi_petstore_example.json"",
        ""operationId"": ""showPetById""
    },
    ""httpResponse"": {
        ""body"": ""some_response_body""
    }
}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
    "httpRequest": {
        "specUrlOrPayload": "https://raw.githubusercontent.com/mock-server/mockserver-monorepo/master/mockserver/mockserver-integration-testing/src/main/resources/org/mockserver/openapi/openapi_petstore_example.json",
        "operationId": "showPetById"
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
// OpenAPI matchers are not supported in the PHP client;
// use the REST API directly
$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'PUT',
    CURLOPT_POSTFIELDS => json_encode([[
        'httpRequest' => [
            'specUrlOrPayload' => 'https://raw.githubusercontent.com/mock-server/mockserver-monorepo/master/mockserver/mockserver-integration-testing/src/main/resources/org/mockserver/openapi/openapi_petstore_example.json',
            'operationId' => 'showPetById',
        ],
        'httpResponse' => ['body' => 'some_response_body'],
    ]]),
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => ['Content-Type: application/json; charset=utf-8'],
]);
curl_exec($ch);
curl_close($ch);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest": {
        "specUrlOrPayload": "https://raw.githubusercontent.com/mock-server/mockserver-monorepo/master/mockserver/mockserver-integration-testing/src/main/resources/org/mockserver/openapi/openapi_petstore_example.json",
        "operationId": "showPetById"
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}'

See REST API for full JSON specification

new MockServerClient("localhost", 1080)
    .when(
        openAPI(
            "file:/path/to/openapi_petstore_example.json"
        )
    )
    .respond(
        response()
            .withBody("some_response_body")
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "specUrlOrPayload": "file:/path/to/openapi_petstore_example.json"
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import Expectation

client = MockServerClient("localhost", 1080)
client.upsert(Expectation.from_dict({
    "httpRequest": {
        "specUrlOrPayload": "file:/path/to/openapi_petstore_example.json"
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}))
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.upsert(MockServer::Expectation.from_hash({
    "httpRequest": {
        "specUrlOrPayload": "file:/path/to/openapi_petstore_example.json"
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}))
package main

import (
    "bytes"
    "net/http"
)

func main() {
    body := []byte(`{
    "httpRequest": {
        "specUrlOrPayload": "file:/path/to/openapi_petstore_example.json"
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}`)
    req, _ := http.NewRequest("PUT",
        "http://localhost:1080/mockserver/expectation",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    http.DefaultClient.Do(req)
}
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
    ""httpRequest"": {
        ""specUrlOrPayload"": ""file:/path/to/openapi_petstore_example.json""
    },
    ""httpResponse"": {
        ""body"": ""some_response_body""
    }
}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
    "httpRequest": {
        "specUrlOrPayload": "file:/path/to/openapi_petstore_example.json"
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
// OpenAPI matchers are not supported in the PHP client;
// use the REST API directly
$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'PUT',
    CURLOPT_POSTFIELDS => json_encode([[
        'httpRequest' => [
            'specUrlOrPayload' => 'file:/path/to/openapi_petstore_example.json',
        ],
        'httpResponse' => ['body' => 'some_response_body'],
    ]]),
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => ['Content-Type: application/json; charset=utf-8'],
]);
curl_exec($ch);
curl_close($ch);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest": {
        "specUrlOrPayload": "file:/path/to/openapi_petstore_example.json"
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}'

See REST API for full JSON specification

new MockServerClient("localhost", 1080)
    .when(
        openAPI(
            "org/mockserver/openapi/openapi_petstore_example.json"
        )
    )
    .respond(
        response()
            .withBody("some_response_body")
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "specUrlOrPayload": "org/mockserver/openapi/openapi_petstore_example.json"
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import Expectation

client = MockServerClient("localhost", 1080)
client.upsert(Expectation.from_dict({
    "httpRequest": {
        "specUrlOrPayload": "org/mockserver/openapi/openapi_petstore_example.json"
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}))
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.upsert(MockServer::Expectation.from_hash({
    "httpRequest": {
        "specUrlOrPayload": "org/mockserver/openapi/openapi_petstore_example.json"
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}))
package main

import (
    "bytes"
    "net/http"
)

func main() {
    body := []byte(`{
    "httpRequest": {
        "specUrlOrPayload": "org/mockserver/openapi/openapi_petstore_example.json"
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}`)
    req, _ := http.NewRequest("PUT",
        "http://localhost:1080/mockserver/expectation",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    http.DefaultClient.Do(req)
}
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
    ""httpRequest"": {
        ""specUrlOrPayload"": ""org/mockserver/openapi/openapi_petstore_example.json""
    },
    ""httpResponse"": {
        ""body"": ""some_response_body""
    }
}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
    "httpRequest": {
        "specUrlOrPayload": "org/mockserver/openapi/openapi_petstore_example.json"
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
// OpenAPI matchers are not supported in the PHP client;
// use the REST API directly
$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'PUT',
    CURLOPT_POSTFIELDS => json_encode([[
        'httpRequest' => [
            'specUrlOrPayload' => 'org/mockserver/openapi/openapi_petstore_example.json',
        ],
        'httpResponse' => ['body' => 'some_response_body'],
    ]]),
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => ['Content-Type: application/json; charset=utf-8'],
]);
curl_exec($ch);
curl_close($ch);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest": {
        "specUrlOrPayload": "org/mockserver/openapi/openapi_petstore_example.json"
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}'

See REST API for full JSON specification

new MockServerClient("localhost", 1080)
    .when(
        new OpenAPIDefinition()
            .withSpecUrlOrPayload(
                FileReader.readFileFromClassPathOrPath("org/mockserver/openapi/openapi_petstore_example.json")
            )
            .withOperationId("listPets")
    )
    .respond(
        response()
            .withBody("some_response_body")
    );
var fs = require('fs');
try {
    var mockServerClient = require('mockserver-client').mockServerClient;
    mockServerClient("localhost", 1080).mockAnyResponse({
        "httpRequest": {
            "specUrlOrPayload": fs.readFileSync("/path/to/openapi_petstore_example.json", "utf8"),
            "operationId": "showPetById"
        },
        "httpResponse": {
            "body": "some_response_body"
        }
    }).then(
        function () {
            console.log("expectation created");
        },
        function (error) {
            console.log(error);
        }
    );
} catch(e) {
    console.log('Error:', e.stack);
}

See REST API for full JSON specification

import json
from mockserver.client import MockServerClient
from mockserver.models import Expectation

client = MockServerClient("localhost", 1080)
with open("/path/to/openapi_petstore_example.json") as f:
    spec = json.load(f)
client.upsert(Expectation.from_dict({
    "httpRequest": {
        "specUrlOrPayload": spec,
        "operationId": "listPets"
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}))
require 'mockserver-client'
require 'json'

client = MockServer::Client.new('localhost', 1080)
spec = JSON.parse(File.read('/path/to/openapi_petstore_example.json'))
client.upsert(MockServer::Expectation.from_hash({
    "httpRequest": {
        "specUrlOrPayload": spec,
        "operationId": "showPetById"
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}))
package main

import (
    "bytes"
    "fmt"
    "net/http"
    "os"
)

func main() {
    spec, _ := os.ReadFile("/path/to/openapi_petstore_example.json")
    body := []byte(fmt.Sprintf(`{
    "httpRequest": {
        "specUrlOrPayload": %s,
        "operationId": "listPets"
    },
    "httpResponse": {
        "body": "some_response_body"
    }
}`, string(spec)))
    req, _ := http.NewRequest("PUT",
        "http://localhost:1080/mockserver/expectation",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    http.DefaultClient.Do(req)
}
using System.IO;
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var spec = File.ReadAllText("/path/to/openapi_petstore_example.json");
var json = $@"{{
    ""httpRequest"": {{
        ""specUrlOrPayload"": {spec},
        ""operationId"": ""listPets""
    }},
    ""httpResponse"": {{
        ""body"": ""some_response_body""
    }}
}}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;
use std::fs;

let client = Client::new();
let spec = fs::read_to_string("/path/to/openapi_petstore_example.json").unwrap();
let body = format!(r#"{{
    "httpRequest": {{
        "specUrlOrPayload": {},
        "operationId": "listPets"
    }},
    "httpResponse": {{
        "body": "some_response_body"
    }}
}}"#, spec);
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body)
    .send()
    .unwrap();
// OpenAPI matchers are not supported in the PHP client;
// use the REST API directly
$specJson = file_get_contents('/path/to/openapi_petstore_example.json');
$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'PUT',
    CURLOPT_POSTFIELDS => json_encode([[
        'httpRequest' => [
            'specUrlOrPayload' => json_decode($specJson, true),
            'operationId' => 'listPets',
        ],
        'httpResponse' => ['body' => 'some_response_body'],
    ]]),
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => ['Content-Type: application/json; charset=utf-8'],
]);
curl_exec($ch);
curl_close($ch);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d "{
    \"httpRequest\": {
        \"specUrlOrPayload\": `cat /path/to/openapi_petstore_example.json`
    },
    \"httpResponse\": {
        \"body\": \"some_response_body\"
    }
}"
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest" : {
      "specUrlOrPayload" : {
        "openapi" : "3.0.0",
        "info" : {
          "version" : "1.0.0",
          "title" : "Swagger Petstore",
          "license" : {
            "name" : "MIT"
          }
        },
        "servers" : [ {
          "url" : "http://petstore.swagger.io/v1"
        } ],
        "paths" : {
          "/pets" : {
            "get" : {
              "summary" : "List all pets",
              "operationId" : "listPets",
              "tags" : [ "pets" ],
              "parameters" : [ {
                "name" : "limit",
                "in" : "query",
                "description" : "How many items to return at one time (max 100)",
                "required" : false,
                "schema" : {
                  "type" : "integer",
                  "format" : "int32"
                }
              } ],
              "responses" : {
                "200" : {
                  "description" : "A paged array of pets",
                  "headers" : {
                    "x-next" : {
                      "description" : "A link to the next page of responses",
                      "schema" : {
                        "type" : "string"
                      }
                    }
                  },
                  "content" : {
                    "application/json" : {
                      "schema" : {
                        "$ref" : "#/components/schemas/Pets"
                      }
                    }
                  }
                },
                "500" : {
                  "description" : "unexpected error",
                  "content" : {
                    "application/json" : {
                      "schema" : {
                        "$ref" : "#/components/schemas/Error"
                      }
                    }
                  }
                },
                "default" : {
                  "description" : "unexpected error",
                  "content" : {
                    "application/json" : {
                      "schema" : {
                        "$ref" : "#/components/schemas/Error"
                      }
                    }
                  }
                }
              }
            },
            "post" : {
              "summary" : "Create a pet",
              "operationId" : "createPets",
              "tags" : [ "pets" ],
              "requestBody" : {
                "description" : "a pet",
                "required" : true,
                "content" : {
                  "application/json" : {
                    "schema" : {
                      "$ref" : "#/components/schemas/Pet"
                    }
                  },
                  "*/*" : {
                    "schema" : {
                      "$ref" : "#/components/schemas/Pet"
                    }
                  }
                }
              },
              "responses" : {
                "201" : {
                  "description" : "Null response"
                },
                "400" : {
                  "description" : "unexpected error",
                  "content" : {
                    "application/json" : {
                      "schema" : {
                        "$ref" : "#/components/schemas/Error"
                      }
                    }
                  }
                },
                "500" : {
                  "description" : "unexpected error",
                  "content" : {
                    "application/json" : {
                      "schema" : {
                        "$ref" : "#/components/schemas/Error"
                      }
                    }
                  }
                },
                "default" : {
                  "description" : "unexpected error",
                  "content" : {
                    "application/json" : {
                      "schema" : {
                        "$ref" : "#/components/schemas/Error"
                      }
                    }
                  }
                }
              }
            }
          },
          "/pets/{petId}" : {
            "get" : {
              "summary" : "Info for a specific pet",
              "operationId" : "showPetById",
              "tags" : [ "pets" ],
              "parameters" : [ {
                "name" : "petId",
                "in" : "path",
                "required" : true,
                "description" : "The id of the pet to retrieve",
                "schema" : {
                  "type" : "string"
                }
              }, {
                "in" : "header",
                "name" : "X-Request-ID",
                "schema" : {
                  "type" : "string",
                  "format" : "uuid"
                },
                "required" : true
              } ],
              "responses" : {
                "200" : {
                  "description" : "Expected response to a valid request",
                  "content" : {
                    "application/json" : {
                      "schema" : {
                        "$ref" : "#/components/schemas/Pet"
                      }
                    }
                  }
                },
                "400" : {
                  "description" : "unexpected error",
                  "content" : {
                    "application/json" : {
                      "schema" : {
                        "$ref" : "#/components/schemas/Error"
                      }
                    }
                  }
                },
                "500" : {
                  "description" : "unexpected error",
                  "content" : {
                    "application/json" : {
                      "schema" : {
                        "$ref" : "#/components/schemas/Error"
                      }
                    }
                  }
                },
                "default" : {
                  "description" : "unexpected error",
                  "content" : {
                    "application/json" : {
                      "schema" : {
                        "$ref" : "#/components/schemas/Error"
                      }
                    }
                  }
                }
              }
            }
          },
          "/some/path" : {
            "get" : {
              "summary" : "Additional request with extra matchers",
              "operationId" : "somePath",
              "tags" : [ "pets" ],
              "parameters" : [ {
                "name" : "limit",
                "in" : "query",
                "description" : "How many items to return at one time (max 100)",
                "required" : false,
                "schema" : {
                  "type" : "integer",
                  "format" : "int32"
                }
              }, {
                "in" : "header",
                "name" : "X-Request-ID",
                "schema" : {
                  "type" : "string",
                  "format" : "uuid"
                },
                "required" : true
              } ],
              "responses" : {
                "200" : {
                  "description" : "Expected response to a valid request",
                  "content" : {
                    "application/json" : {
                      "schema" : {
                        "$ref" : "#/components/schemas/Pet"
                      }
                    }
                  }
                },
                "default" : {
                  "description" : "unexpected error",
                  "content" : {
                    "application/json" : {
                      "schema" : {
                        "$ref" : "#/components/schemas/Error"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "components" : {
          "schemas" : {
            "Pet" : {
              "type" : "object",
              "required" : [ "id", "name" ],
              "properties" : {
                "id" : {
                  "type" : "integer",
                  "format" : "int64"
                },
                "name" : {
                  "type" : "string"
                },
                "tag" : {
                  "type" : "string"
                }
              }
            },
            "Pets" : {
              "type" : "array",
              "items" : {
                "$ref" : "#/components/schemas/Pet"
              }
            },
            "Error" : {
              "type" : "object",
              "required" : [ "code", "message" ],
              "properties" : {
                "code" : {
                  "type" : "integer",
                  "format" : "int32"
                },
                "message" : {
                  "type" : "string"
                }
              }
            }
          }
        }
      },
      "operationId" : "listPets"
    },
    "httpResponse" : {
      "body" : "some_response_body"
    }
  }'

See REST API for full JSON specification

new MockServerClient("localhost", 1080)
    .when(
        new OpenAPIDefinition()
            .withSpecUrlOrPayload(
                "\nopenapi: 3.0.0\ninfo:\n  version: 1.0.0\n  title: Swagger Petstore\n  license:\n    name: MIT\nservers:\n  - url: http://petstore.swagger.io/v1\npaths:\n  /pets:\n    get:\n      summary: List all pets\n      operationId: listPets\n      tags:\n        - pets\n      parameters:\n        - name: limit\n          in: query\n          description: How many items to return at one time (max 100)\n          required: false\n          schema:\n            type: integer\n            format: int32\n      responses:\n        '200':\n          description: A paged array of pets\n          headers:\n            x-next:\n              description: A link to the next page of responses\n              schema:\n                type: string\n              examples:\n                two:\n                  value: \"/pets?query=752cd724e0d7&page=2\"\n                end:\n                  value: \"\"\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/Pets'\n        '500':\n          description: unexpected error\n          headers:\n            x-code:\n              description: The error code\n              schema:\n                type: integer\n                format: int32\n                example: 90\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/Error'\n        default:\n          description: unexpected error\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/Error'\n    post:\n      summary: Create a pet\n      operationId: createPets\n      tags:\n        - pets\n      requestBody:\n        description: a pet\n        required: true\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/Pet'\n          '*/*':\n            schema:\n              $ref: '#/components/schemas/Pet'\n      responses:\n        '201':\n          description: Null response\n        '400':\n          description: unexpected error\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/Error'\n        '500':\n          description: unexpected error\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/Error'\n        default:\n          description: unexpected error\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/Error'\n  /pets/{petId}:\n    get:\n      summary: Info for a specific pet\n      operationId: showPetById\n      tags:\n        - pets\n      parameters:\n        - name: petId\n          in: path\n          required: true\n          description: The id of the pet to retrieve\n          schema:\n            type: string\n        - in: header\n          name: X-Request-ID\n          schema:\n            type: string\n            format: uuid\n          required: true\n      responses:\n        '200':\n          description: Expected response to a valid request\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/Pet'\n              examples:\n                Crumble:\n                  value:\n                    id: 2\n                    name: Crumble\n                    tag: dog\n                Boots:\n                  value:\n                    id: 3\n                    name: Boots\n                    tag: cat\n        '500':\n          description: unexpected error\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/Error'\n        default:\n          description: unexpected error\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/Error'\ncomponents:\n  schemas:\n    Pet:\n      type: object\n      required:\n        - id\n        - name\n      properties:\n        id:\n          type: integer\n          format: int64\n        name:\n          type: string\n        tag:\n          type: string\n      example:\n        id: 1\n        name: Scruffles\n        tag: dog\n    Pets:\n      type: array\n      items:\n        $ref: '#/components/schemas/Pet'\n    Error:\n      type: object\n      required:\n        - code\n        - message\n      properties:\n        code:\n          type: integer\n          format: int32\n        message:\n          type: string\n",
      "operationId" : "listPets"
    },
    "times" : {
      "unlimited" : true
    },
    "timeToLive" : {
      "unlimited" : true
    },
    "httpResponse" : {
      "body" : "some_response_body"
    }
  }'

See REST API for full JSON specification

new MockServerClient("localhost", 1080)
    .when(
        new OpenAPIDefinition()
            .withSpecUrlOrPayload(
               FileReader.readFileFromClassPathOrPath("org/mockserver/openapi/openapi_petstore_example.json")
            )
            .withOperationId("listPets"),
        Times.exactly(2)
    )
    .respond(
        response()
            .withBody("some_response_body")
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest":{
        "specUrlOrPayload": "https://raw.githubusercontent.com/mock-server/mockserver-monorepo/master/mockserver/mockserver-integration-testing/src/main/resources/org/mockserver/openapi/openapi_petstore_example.json",
        "operationId": "showPetById"
    },
    "httpResponse":{
        "statusCode": 200,
        "body": "some_body"
    },
    "times": {
        "remainingTimes": 2
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import Expectation

client = MockServerClient("localhost", 1080)
client.upsert(Expectation.from_dict({
    "httpRequest": {
        "specUrlOrPayload": "https://raw.githubusercontent.com/mock-server/mockserver-monorepo/master/mockserver/mockserver-integration-testing/src/main/resources/org/mockserver/openapi/openapi_petstore_example.json",
        "operationId": "showPetById"
    },
    "httpResponse": {
        "statusCode": 200,
        "body": "some_body"
    },
    "times": {
        "remainingTimes": 2
    }
}))
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.upsert(MockServer::Expectation.from_hash({
    "httpRequest": {
        "specUrlOrPayload": "https://raw.githubusercontent.com/mock-server/mockserver-monorepo/master/mockserver/mockserver-integration-testing/src/main/resources/org/mockserver/openapi/openapi_petstore_example.json",
        "operationId": "showPetById"
    },
    "httpResponse": {
        "statusCode": 200,
        "body": "some_body"
    },
    "times": {
        "remainingTimes": 2
    }
}))
package main

import (
    "bytes"
    "net/http"
)

func main() {
    body := []byte(`{
    "httpRequest":{
        "specUrlOrPayload": "https://raw.githubusercontent.com/mock-server/mockserver-monorepo/master/mockserver/mockserver-integration-testing/src/main/resources/org/mockserver/openapi/openapi_petstore_example.json",
        "operationId": "showPetById"
    },
    "httpResponse":{
        "statusCode": 200,
        "body": "some_body"
    },
    "times": {
        "remainingTimes": 2
    }
}`)
    req, _ := http.NewRequest("PUT",
        "http://localhost:1080/mockserver/expectation",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    http.DefaultClient.Do(req)
}
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
    ""httpRequest"":{
        ""specUrlOrPayload"": ""https://raw.githubusercontent.com/mock-server/mockserver-monorepo/master/mockserver/mockserver-integration-testing/src/main/resources/org/mockserver/openapi/openapi_petstore_example.json"",
        ""operationId"": ""showPetById""
    },
    ""httpResponse"":{
        ""statusCode"": 200,
        ""body"": ""some_body""
    },
    ""times"": {
        ""remainingTimes"": 2
    }
}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
    "httpRequest":{
        "specUrlOrPayload": "https://raw.githubusercontent.com/mock-server/mockserver-monorepo/master/mockserver/mockserver-integration-testing/src/main/resources/org/mockserver/openapi/openapi_petstore_example.json",
        "operationId": "showPetById"
    },
    "httpResponse":{
        "statusCode": 200,
        "body": "some_body"
    },
    "times": {
        "remainingTimes": 2
    }
}"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
// OpenAPI matchers are not supported in the PHP client;
// use the REST API directly
$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'PUT',
    CURLOPT_POSTFIELDS => json_encode([[
        'httpRequest' => [
            'specUrlOrPayload' => 'https://raw.githubusercontent.com/mock-server/mockserver-monorepo/master/mockserver/mockserver-integration-testing/src/main/resources/org/mockserver/openapi/openapi_petstore_example.json',
            'operationId' => 'showPetById',
        ],
        'httpResponse' => ['statusCode' => 200, 'body' => 'some_body'],
        'times' => ['remainingTimes' => 2],
    ]]),
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => ['Content-Type: application/json; charset=utf-8'],
]);
curl_exec($ch);
curl_close($ch);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest":{
        "specUrlOrPayload": "https://raw.githubusercontent.com/mock-server/mockserver-monorepo/master/mockserver/mockserver-integration-testing/src/main/resources/org/mockserver/openapi/openapi_petstore_example.json",
        "operationId": "showPetById"
    },
    "httpResponse":{
        "statusCode": 200,
        "body": "some_body"
    },
    "times": {
        "remainingTimes": 2
    }
}'

See REST API for full JSON specification

new MockServerClient("localhost", 1080)
    .upsert(
        new Expectation(
            openAPI(
               "org/mockserver/openapi/openapi_petstore_example.json",
               "showPetById"
            ),
            Times.once(),
            TimeToLive.exactly(TimeUnit.SECONDS, 60L),
            100
        )
        .withId("630a6e5b-9d61-4668-a18f-a0d3df558583")
        .thenRespond(response().withBody("some_response_body"))
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "id": "630a6e5b-9d61-4668-a18f-a0d3df558583",
    "priority": 0,
    "httpRequest":{
        "specUrlOrPayload": "https://raw.githubusercontent.com/mock-server/mockserver-monorepo/master/mockserver/mockserver-integration-testing/src/main/resources/org/mockserver/openapi/openapi_petstore_example.json",
        "operationId": "showPetById"
    },
    "httpResponse":{
        "statusCode": 200,
        "body": "some_response_body"
    },
    "times":{
        "unlimited": true
    },
    "timeToLive":{
        "unlimited": true
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import Expectation

client = MockServerClient("localhost", 1080)
client.upsert(Expectation.from_dict({
    "id": "630a6e5b-9d61-4668-a18f-a0d3df558583",
    "priority": 0,
    "httpRequest": {
        "specUrlOrPayload": "https://raw.githubusercontent.com/mock-server/mockserver-monorepo/master/mockserver/mockserver-integration-testing/src/main/resources/org/mockserver/openapi/openapi_petstore_example.json",
        "operationId": "showPetById"
    },
    "httpResponse": {
        "statusCode": 200,
        "body": "some_response_body"
    },
    "times": {
        "unlimited": True
    },
    "timeToLive": {
        "unlimited": True
    }
}))
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.upsert(MockServer::Expectation.from_hash({
    "id": "630a6e5b-9d61-4668-a18f-a0d3df558583",
    "priority": 0,
    "httpRequest": {
        "specUrlOrPayload": "https://raw.githubusercontent.com/mock-server/mockserver-monorepo/master/mockserver/mockserver-integration-testing/src/main/resources/org/mockserver/openapi/openapi_petstore_example.json",
        "operationId": "showPetById"
    },
    "httpResponse": {
        "statusCode": 200,
        "body": "some_response_body"
    },
    "times": {
        "unlimited": true
    },
    "timeToLive": {
        "unlimited": true
    }
}))
package main

import (
    "bytes"
    "net/http"
)

func main() {
    body := []byte(`{
    "id": "630a6e5b-9d61-4668-a18f-a0d3df558583",
    "priority": 0,
    "httpRequest":{
        "specUrlOrPayload": "https://raw.githubusercontent.com/mock-server/mockserver-monorepo/master/mockserver/mockserver-integration-testing/src/main/resources/org/mockserver/openapi/openapi_petstore_example.json",
        "operationId": "showPetById"
    },
    "httpResponse":{
        "statusCode": 200,
        "body": "some_response_body"
    },
    "times":{
        "unlimited": true
    },
    "timeToLive":{
        "unlimited": true
    }
}`)
    req, _ := http.NewRequest("PUT",
        "http://localhost:1080/mockserver/expectation",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    http.DefaultClient.Do(req)
}
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
    ""id"": ""630a6e5b-9d61-4668-a18f-a0d3df558583"",
    ""priority"": 0,
    ""httpRequest"":{
        ""specUrlOrPayload"": ""https://raw.githubusercontent.com/mock-server/mockserver-monorepo/master/mockserver/mockserver-integration-testing/src/main/resources/org/mockserver/openapi/openapi_petstore_example.json"",
        ""operationId"": ""showPetById""
    },
    ""httpResponse"":{
        ""statusCode"": 200,
        ""body"": ""some_response_body""
    },
    ""times"":{
        ""unlimited"": true
    },
    ""timeToLive"":{
        ""unlimited"": true
    }
}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
    "id": "630a6e5b-9d61-4668-a18f-a0d3df558583",
    "priority": 0,
    "httpRequest":{
        "specUrlOrPayload": "https://raw.githubusercontent.com/mock-server/mockserver-monorepo/master/mockserver/mockserver-integration-testing/src/main/resources/org/mockserver/openapi/openapi_petstore_example.json",
        "operationId": "showPetById"
    },
    "httpResponse":{
        "statusCode": 200,
        "body": "some_response_body"
    },
    "times":{
        "unlimited": true
    },
    "timeToLive":{
        "unlimited": true
    }
}"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
// OpenAPI matchers are not supported in the PHP client;
// use the REST API directly
$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'PUT',
    CURLOPT_POSTFIELDS => json_encode([[
        'id' => '630a6e5b-9d61-4668-a18f-a0d3df558583',
        'priority' => 0,
        'httpRequest' => [
            'specUrlOrPayload' => 'https://raw.githubusercontent.com/mock-server/mockserver-monorepo/master/mockserver/mockserver-integration-testing/src/main/resources/org/mockserver/openapi/openapi_petstore_example.json',
            'operationId' => 'showPetById',
        ],
        'httpResponse' => ['statusCode' => 200, 'body' => 'some_response_body'],
        'times' => ['unlimited' => true],
        'timeToLive' => ['unlimited' => true],
    ]]),
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => ['Content-Type: application/json; charset=utf-8'],
]);
curl_exec($ch);
curl_close($ch);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "id": "630a6e5b-9d61-4668-a18f-a0d3df558583",
    "priority": 0,
    "httpRequest":{
        "specUrlOrPayload": "https://raw.githubusercontent.com/mock-server/mockserver-monorepo/master/mockserver/mockserver-integration-testing/src/main/resources/org/mockserver/openapi/openapi_petstore_example.json",
        "operationId": "showPetById"
    },
    "httpResponse":{
        "statusCode": 200,
        "body": "some_response_body"
    },
    "times":{
        "unlimited": true
    },
    "timeToLive":{
        "unlimited": true
    }
}'

See REST API for full JSON specification

 

Actions

Actions can be one of the following types:

If no action is present for a request because no request matcher was matched then:

  • if MockServer is being used as a proxy the request is proxied to its destination un-modified
  • if the request host header does not match the hostname or IP the request automatically proxied to the host header
 

A response action can be:

The following code examples show how to create different response actions.

new MockServerClient("localhost", 1080)
    // this request matcher matches every request
    .when(
        request()
    )
    .respond(
        response()
            .withBody("some_response_body")
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    // if no request matcher is specified then every request matched
    "httpResponse": {
        "body": "some_response_body"
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import HttpRequest, HttpResponse

client = MockServerClient("localhost", 1080)
# this request matcher matches every request
client.when(
    HttpRequest.request()
).respond(
    HttpResponse.response(body="some_response_body")
)
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
# this request matcher matches every request
client.when(
    MockServer::HttpRequest.new
).respond(
    MockServer::HttpResponse.new(body: 'some_response_body')
)
import mockserver "github.com/mock-server/mockserver-monorepo/mockserver-client-go"

client := mockserver.New("localhost", 1080)
// this request matcher matches every request
client.When(
    mockserver.Request(),
).Respond(
    mockserver.Response().Body("some_response_body"),
)
using MockServer.Client;
using MockServer.Client.Models;

using var client = new MockServerClient("localhost", 1080);
// this request matcher matches every request
client.When(
    HttpRequest.Request()
).Respond(
    HttpResponse.Response().WithBody("some_response_body")
);
use mockserver_client::{ClientBuilder, HttpRequest, HttpResponse};

let client = ClientBuilder::new("localhost", 1080).build().unwrap();
// this request matcher matches every request
client.when(HttpRequest::new())
    .respond(HttpResponse::new().body("some_response_body"))
    .unwrap();
use MockServer\MockServerClient;
use MockServer\HttpRequest;
use MockServer\HttpResponse;

$client = new MockServerClient('localhost', 1080);
$client->when(
    HttpRequest::request()
)->respond(
    HttpResponse::response()
        ->body('some_response_body')
);
# if no request matcher is specified then every request matched
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpResponse": {
        "body": "some_response_body"
    }
}'

See REST API for full JSON specification

FileBody loads the response content from a file at response time, rather than embedding the content directly in the expectation. This is useful when the response payload is large (e.g. sample JSON or XML files), generated externally, or shared across multiple expectations. The file path can be absolute or relative to the working directory.

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/api/data")
    )
    .respond(
        response()
            .withBodyFromFile("/path/to/response.json")
    );

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/api/data")
    )
    .respond(
        response()
            .withBodyFromFile("/path/to/response.json", MediaType.APPLICATION_JSON)
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "path": "/api/data"
    },
    "httpResponse": {
        "body": {
            "type": "FILE",
            "filePath": "/path/to/response.json",
            "contentType": "application/json"
        }
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import Expectation

client = MockServerClient("localhost", 1080)
client.upsert(Expectation.from_dict({
    "httpRequest": {
        "path": "/api/data"
    },
    "httpResponse": {
        "body": {
            "type": "FILE",
            "filePath": "/path/to/response.json",
            "contentType": "application/json"
        }
    }
}))
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.upsert(MockServer::Expectation.from_hash({
    "httpRequest": {
        "path": "/api/data"
    },
    "httpResponse": {
        "body": {
            "type": "FILE",
            "filePath": "/path/to/response.json",
            "contentType": "application/json"
        }
    }
}))
package main

import (
    "bytes"
    "net/http"
)

func main() {
    body := []byte(`{
    "httpRequest": {
        "path": "/api/data"
    },
    "httpResponse": {
        "body": {
            "type": "FILE",
            "filePath": "/path/to/response.json",
            "contentType": "application/json"
        }
    }
}`)
    req, _ := http.NewRequest("PUT",
        "http://localhost:1080/mockserver/expectation",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    http.DefaultClient.Do(req)
}
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
    ""httpRequest"": {
        ""path"": ""/api/data""
    },
    ""httpResponse"": {
        ""body"": {
            ""type"": ""FILE"",
            ""filePath"": ""/path/to/response.json"",
            ""contentType"": ""application/json""
        }
    }
}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
    "httpRequest": {
        "path": "/api/data"
    },
    "httpResponse": {
        "body": {
            "type": "FILE",
            "filePath": "/path/to/response.json",
            "contentType": "application/json"
        }
    }
}"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
$json = <<<'JSON'
{
    "httpRequest": {
        "path": "/api/data"
    },
    "httpResponse": {
        "body": {
            "type": "FILE",
            "filePath": "/path/to/response.json",
            "contentType": "application/json"
        }
    }
}
JSON;

$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_POSTFIELDS     => $json,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json; charset=utf-8'],
    CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
curl_close($ch);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest": {
        "path": "/api/data"
    },
    "httpResponse": {
        "body": {
            "type": "FILE",
            "filePath": "/path/to/response.json",
            "contentType": "application/json"
        }
    }
}'

See REST API for full JSON specification

new MockServerClient("localhost", 1080)
    // this request matcher matches every request
    .when(
        request()
    )
    .respond(
        response()
            .withHeader(
                CONTENT_TYPE.toString(),
                MediaType.create("text", "plain").withCharset(Charsets.UTF_16).toString()
            )
            .withBody("我说中国话".getBytes(Charsets.UTF_16))
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    // if no request matcher is specified then every request matched
    "httpResponse": {
        "headers": {
            "content-type": ["text/plain; charset=utf-16"]
        },
        "body": {
            "type": "BINARY",
            "base64Bytes": "/v9iEYv0Ti1W/Yvd"
        }
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import Expectation

client = MockServerClient("localhost", 1080)
client.upsert(Expectation.from_dict({
    "httpResponse": {
        "headers": {
            "content-type": ["text/plain; charset=utf-16"]
        },
        "body": {
            "type": "BINARY",
            "base64Bytes": "/v9iEYv0Ti1W/Yvd"
        }
    }
}))
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.upsert(MockServer::Expectation.from_hash({
    "httpResponse": {
        "headers": {
            "content-type": ["text/plain; charset=utf-16"]
        },
        "body": {
            "type": "BINARY",
            "base64Bytes": "/v9iEYv0Ti1W/Yvd"
        }
    }
}))
package main

import (
    "bytes"
    "net/http"
)

func main() {
    body := []byte(`{
    "httpResponse": {
        "headers": {
            "content-type": ["text/plain; charset=utf-16"]
        },
        "body": {
            "type": "BINARY",
            "base64Bytes": "/v9iEYv0Ti1W/Yvd"
        }
    }
}`)
    req, _ := http.NewRequest("PUT",
        "http://localhost:1080/mockserver/expectation",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    http.DefaultClient.Do(req)
}
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
    ""httpResponse"": {
        ""headers"": {
            ""content-type"": [""text/plain; charset=utf-16""]
        },
        ""body"": {
            ""type"": ""BINARY"",
            ""base64Bytes"": ""/v9iEYv0Ti1W/Yvd""
        }
    }
}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
    "httpResponse": {
        "headers": {
            "content-type": ["text/plain; charset=utf-16"]
        },
        "body": {
            "type": "BINARY",
            "base64Bytes": "/v9iEYv0Ti1W/Yvd"
        }
    }
}"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
$json = <<<'JSON'
{
    "httpResponse": {
        "headers": {
            "content-type": ["text/plain; charset=utf-16"]
        },
        "body": {
            "type": "BINARY",
            "base64Bytes": "/v9iEYv0Ti1W/Yvd"
        }
    }
}
JSON;

$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_POSTFIELDS     => $json,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json; charset=utf-8'],
    CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
curl_close($ch);
# if no request matcher is specified then every request matched
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpResponse": {
        "headers": {
            "content-type": ["text/plain; charset=utf-16"]
        },
        "body": {
            "type": "BINARY",
            "base64Bytes": "/v9iEYv0Ti1W/Yvd"
        }
    }
}'

See REST API for full JSON specification

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withMethod("GET")
            .withPath("/farsi_body")
    )
    .respond(
        response()
            .withBody(json("سلام", MediaType.APPLICATION_JSON_UTF_8))
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "method": "GET",
        "path": "/simple"
    },
    "httpResponse": {
        "body": {
            "type": "STRING",
            "string": "سلام",
            "contentType": "text/plain; charset=utf-8"
         }
    },
    "times": {
        "unlimited": true
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import Expectation

client = MockServerClient("localhost", 1080)
client.upsert(Expectation.from_dict({
    "httpRequest": {
        "method": "GET",
        "path": "/simple"
    },
    "httpResponse": {
        "body": {
            "type": "STRING",
            "string": "\u0633\u0644\u0627\u0645",
            "contentType": "text/plain; charset=utf-8"
         }
    },
    "times": {
        "unlimited": true
    }
}))
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.upsert(MockServer::Expectation.from_hash({
    "httpRequest": {
        "method": "GET",
        "path": "/simple"
    },
    "httpResponse": {
        "body": {
            "type": "STRING",
            "string": "\u0633\u0644\u0627\u0645",
            "contentType": "text/plain; charset=utf-8"
         }
    },
    "times": {
        "unlimited": true
    }
}))
package main

import (
    "bytes"
    "net/http"
)

func main() {
    body := []byte(`{
    "httpRequest": {
        "method": "GET",
        "path": "/simple"
    },
    "httpResponse": {
        "body": {
            "type": "STRING",
            "string": "\u0633\u0644\u0627\u0645",
            "contentType": "text/plain; charset=utf-8"
         }
    },
    "times": {
        "unlimited": true
    }
}`)
    req, _ := http.NewRequest("PUT",
        "http://localhost:1080/mockserver/expectation",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    http.DefaultClient.Do(req)
}
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
    ""httpRequest"": {
        ""method"": ""GET"",
        ""path"": ""/simple""
    },
    ""httpResponse"": {
        ""body"": {
            ""type"": ""STRING"",
            ""string"": ""\u0633\u0644\u0627\u0645"",
            ""contentType"": ""text/plain; charset=utf-8""
         }
    },
    ""times"": {
        ""unlimited"": true
    }
}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
    "httpRequest": {
        "method": "GET",
        "path": "/simple"
    },
    "httpResponse": {
        "body": {
            "type": "STRING",
            "string": "\u0633\u0644\u0627\u0645",
            "contentType": "text/plain; charset=utf-8"
         }
    },
    "times": {
        "unlimited": true
    }
}"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
$json = <<<'JSON'
{
    "httpRequest": {
        "method": "GET",
        "path": "/simple"
    },
    "httpResponse": {
        "body": {
            "type": "STRING",
            "string": "سلام",
            "contentType": "text/plain; charset=utf-8"
         }
    },
    "times": {
        "unlimited": true
    }
}
JSON;

$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_POSTFIELDS     => $json,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json; charset=utf-8'],
    CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
curl_close($ch);
curl -v -X PUT http://localhost:1080/mockserver/expectation -H "Content-Type: application/json; charset=utf-8" --data '{
    "httpRequest": {
        "method": "GET",
        "path": "/simple"
    },
    "httpResponse": {
        "body": {
            "type": "STRING",
            "string": "سلام",
            "contentType": "text/plain; charset=utf-8"
         }
    },
    "times": {
        "unlimited": true
    }
}'

See REST API for full JSON specification

new MockServerClient("localhost", 1080)
    // this request matcher matches every request
    .when(
        request()
    )
    .respond(
        response()
            .withBody("some_response_body")
            .withHeader("Content-Type", "plain/text")
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    // if no request matcher is specified then every request matched
    "httpResponse": {
        "headers": {
            "Content-Type": ["plain/text"]
        },
        "body": "some_response_body"
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import HttpRequest, HttpResponse

client = MockServerClient("localhost", 1080)
# this request matcher matches every request
client.when(
    HttpRequest.request()
).respond(
    HttpResponse.response(body="some_response_body")
        .with_header("Content-Type", "plain/text")
)
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
# this request matcher matches every request
client.when(
    MockServer::HttpRequest.new
).respond(
    MockServer::HttpResponse.new(
        body: 'some_response_body',
        headers: [MockServer::KeyToMultiValue.new(
            name: 'Content-Type', values: ['plain/text']
        )]
    )
)
import mockserver "github.com/mock-server/mockserver-monorepo/mockserver-client-go"

client := mockserver.New("localhost", 1080)
// this request matcher matches every request
client.When(
    mockserver.Request(),
).Respond(
    mockserver.Response().
        Body("some_response_body").
        Header("Content-Type", "plain/text"),
)
using MockServer.Client;
using MockServer.Client.Models;

using var client = new MockServerClient("localhost", 1080);
// this request matcher matches every request
client.When(
    HttpRequest.Request()
).Respond(
    HttpResponse.Response()
        .WithBody("some_response_body")
        .WithHeader("Content-Type", "plain/text")
);
use mockserver_client::{ClientBuilder, HttpRequest, HttpResponse};

let client = ClientBuilder::new("localhost", 1080).build().unwrap();
// this request matcher matches every request
client.when(HttpRequest::new())
    .respond(
        HttpResponse::new()
            .body("some_response_body")
            .header("Content-Type", "plain/text")
    )
    .unwrap();
use MockServer\MockServerClient;
use MockServer\HttpRequest;
use MockServer\HttpResponse;

$client = new MockServerClient('localhost', 1080);
$client->when(
    HttpRequest::request()
)->respond(
    HttpResponse::response()
        ->header('Content-Type', 'plain/text')
        ->body('some_response_body')
);
curl -v -X PUT http://localhost:1080/mockserver/expectation -H "Content-Type: application/json; charset=utf-8" --data '{
    "httpResponse": {
        "headers": {
            "Content-Type": ["plain/text"]
        },
        "body": "some_response_body"
    }
}'

See REST API for full JSON specification

Response trailers are trailing headers sent after the response body. They are configured exactly like headers, using trailers instead of headers, and are sent as protocol-appropriate trailing headers: a trailing HEADERS frame for HTTP/2 and HTTP/3, and a chunked trailer section for HTTP/1.1.

HTTP/1.1 caveat: trailers require chunked transfer-encoding, so when trailers are set on an HTTP/1.1 response MockServer automatically switches the response to Transfer-Encoding: chunked and adds a Trailer header announcing the trailer field names (as required by the HTTP specification). Some clients ignore trailers unless they opt in via the TE: trailers request header.

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/some/path")
    )
    .respond(
        response()
            .withBody("some_response_body")
            .withTrailer("X-Checksum", "abc123")
            .withTrailer("X-Signature", "deadbeef")
    );
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpResponse": {
        "body": "some_response_body",
        "trailers": {
            "X-Checksum": ["abc123"],
            "X-Signature": ["deadbeef"]
        }
    }
}'

See REST API for full JSON specification

new MockServerClient("localhost", 1080)
    // this request matcher matches every request
    .when(
        request()
    )
    .respond(
        response()
            .withBody("some_response_body")
            .withHeader("Content-Type", "plain/text")
            .withCookie("Session", "97d43b1e-fe03-4855-926a-f448eddac32f")
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    // if no request matcher is specified then every request matched
    "httpResponse": {
        "headers": {
            "Content-Type": ["plain/text"]
        },
        "cookies": {
            "Session": "97d43b1e-fe03-4855-926a-f448eddac32f"
        },
        "body": "some_response_body"
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import HttpRequest, HttpResponse

client = MockServerClient("localhost", 1080)
# this request matcher matches every request
client.when(
    HttpRequest.request()
).respond(
    HttpResponse.response(body="some_response_body")
        .with_header("Content-Type", "plain/text")
        .with_cookie("Session", "97d43b1e-fe03-4855-926a-f448eddac32f")
)
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
# this request matcher matches every request
client.when(
    MockServer::HttpRequest.new
).respond(
    MockServer::HttpResponse.new(
        body: 'some_response_body',
        headers: [MockServer::KeyToMultiValue.new(
            name: 'Content-Type', values: ['plain/text']
        )],
        cookies: [MockServer::KeyToMultiValue.new(
            name: 'Session', values: ['97d43b1e-fe03-4855-926a-f448eddac32f']
        )]
    )
)
import mockserver "github.com/mock-server/mockserver-monorepo/mockserver-client-go"

client := mockserver.New("localhost", 1080)
// this request matcher matches every request
client.When(
    mockserver.Request(),
).Respond(
    mockserver.Response().
        Body("some_response_body").
        Header("Content-Type", "plain/text").
        Cookie("Session", "97d43b1e-fe03-4855-926a-f448eddac32f"),
)
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
    ""httpResponse"": {
        ""headers"": {
            ""Content-Type"": [""plain/text""]
        },
        ""cookies"": {
            ""Session"": ""97d43b1e-fe03-4855-926a-f448eddac32f""
        },
        ""body"": ""some_response_body""
    }
}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
    "httpResponse": {
        "headers": {
            "Content-Type": ["plain/text"]
        },
        "cookies": {
            "Session": "97d43b1e-fe03-4855-926a-f448eddac32f"
        },
        "body": "some_response_body"
    }
}"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
use MockServer\MockServerClient;
use MockServer\HttpRequest;
use MockServer\HttpResponse;

$client = new MockServerClient('localhost', 1080);
$client->when(
    HttpRequest::request()
)->respond(
    HttpResponse::response()
        ->header('Content-Type', 'plain/text')
        ->cookie('Session', '97d43b1e-fe03-4855-926a-f448eddac32f')
        ->body('some_response_body')
);
curl -v -X PUT http://localhost:1080/mockserver/expectation -H "Content-Type: application/json; charset=utf-8" --data '{
    "httpResponse": {
        "headers": {
            "Content-Type": ["plain/text"]
        },
        "cookies": {
            "Session": "97d43b1e-fe03-4855-926a-f448eddac32f"
        },
        "body": "some_response_body"
    }
}'

See REST API for full JSON specification

Note for WAR deployments: Jakarta Servlet 6 (Tomcat 11+, Jetty 12+, WildFly 32+) removed support for custom HTTP reason phrases via HttpServletResponse.setStatus(int, String), so when MockServer is deployed as a WAR in a Servlet 6 container only the status code is sent on the wire and the reason phrase is silently dropped. The reason phrase still works in MockServer's standalone, Docker, and Netty deployments.

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withMethod("POST")
            .withPath("/some/path")
    )
    .respond(
        response()
            .withStatusCode(418)
            .withReasonPhrase("I'm a teapot")
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "method": "POST",
        "path": "/some/path"
    },
    "httpResponse": {
        "statusCode": 418,
        "reasonPhrase": "I'm a teapot"
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import HttpRequest, HttpResponse

client = MockServerClient("localhost", 1080)
client.when(
    HttpRequest.request(path="/some/path").with_method("POST")
).respond(
    HttpResponse.response()
        .with_status_code(418)
        .with_reason_phrase("I'm a teapot")
)
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.when(
    MockServer::HttpRequest.new(method: 'POST', path: '/some/path')
).respond(
    MockServer::HttpResponse.new(
        status_code: 418,
        reason_phrase: "I'm a teapot"
    )
)
import mockserver "github.com/mock-server/mockserver-monorepo/mockserver-client-go"

client := mockserver.New("localhost", 1080)
client.When(
    mockserver.Request().Method("POST").Path("/some/path"),
).Respond(
    mockserver.Response().
        StatusCode(418).
        ReasonPhrase("I'm a teapot"),
)
using MockServer.Client;
using MockServer.Client.Models;

using var client = new MockServerClient("localhost", 1080);
client.When(
    HttpRequest.Request().WithMethod("POST").WithPath("/some/path")
).Respond(
    HttpResponse.Response()
        .WithStatusCode(418)
        .WithReasonPhrase("I'm a teapot")
);
use mockserver_client::{ClientBuilder, HttpRequest, HttpResponse};

let client = ClientBuilder::new("localhost", 1080).build().unwrap();
client.when(
    HttpRequest::new().method("POST").path("/some/path")
).respond(
    HttpResponse::new().status_code(418)
).unwrap();
// Note: the Rust client does not expose reason_phrase;
// use a raw PUT /mockserver/expectation request for that field
use MockServer\MockServerClient;
use MockServer\HttpRequest;
use MockServer\HttpResponse;

$client = new MockServerClient('localhost', 1080);
$client->when(
    HttpRequest::request()
        ->method('POST')
        ->path('/some/path')
)->respond(
    HttpResponse::response()
        ->statusCode(418)
        ->reasonPhrase('I\'m a teapot')
);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest": {
        "method": "POST",
        "path": "/some/path"
    },
    "httpResponse": {
        "statusCode": 418,
        "reasonPhrase": "I'm a teapot"
    }
}'

See REST API for full JSON specification

byte[] pngBytes = IOUtils.toByteArray(getClass().getClassLoader().getResourceAsStream("org/mockserver/examples/mockserver/test.png"));
new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/ws/rest/user/[0-9]+/icon/[0-9]+\\.png")
    )
    .respond(
        response()
            .withStatusCode(HttpStatusCode.OK_200.code())
            .withHeaders(
                header(CONTENT_TYPE.toString(), MediaType.PNG.toString()),
                header(CONTENT_DISPOSITION.toString(), "form-data; name=\"test.png\"; filename=\"test.png\"")
            )
            .withBody(binary(pngBytes))
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "path": "/ws/rest/user/[0-9]+/icon/[0-9]+\\.png"
    },
    "httpResponse": {
        "statusCode": 200,
        "headers": {
            "content-type": ["image/png"],
            "content-disposition": ["form-data; name=\"test.png\"; filename=\"test.png\""]
        },
        "body": {
            "type": "BINARY",
            "base64Bytes": "iVBORw0KGgoAAAANSUhEUgAAAqwAAAApCAIAAAB/QuwlAAAK+GlDQ1BJQ0MgUHJvZmlsZQAASA2tl3dcU8kWx+fe9EYLICAl9CZIr9JrAAXpYCMkgYQSYgoCVpTFFVwLKiKgrugiiIJrAWQtiAULoljAvkEWFXVdLIiKypvAEvfzPm//e5PP3Pne35w598zcmXzOBYBGZQmFWagKANkCiSg6xJ+RmJTMIDwGWKAF8EAf2LHYYqFfVFQE+NfyoRcg8s5bNnJf/2r2vztUOVwxGwAkCnancsTsbMjHYH3PFookAGDqoG68RCKUcxdkdREMELJMzumT/F7OqROMJU7YxEYHAIDVBYBIZbFE6QBQLaDOyGWnQz/UUMh2Ag5fADkPsjebx+JAboU8Izs7R85/QLZI/Yef9H8wi5Wq8MlipSt4ci5wJHxwIF8szGLlT9z8Py/ZWVK4XhPFEF6pPFFoNGwT4ZpVZ+aEK1iQOidySufDGU0xTxoaN8VscQBcy8mxHFZg+BRLM+P8ppglgvS3DV/CjJ1iUU60wr8ga458f0zEwOMyFcwVB8VM6Wn8YOYUF/BiE6Y4lx8/Z4rFmTGKGAp4AQpdJI1WxJwmClbMMVsMR/79XDbr+7MkvFj5O56Ih8MNDJpiriBOEY9Q4q/wI8ya2N8T9tysEIUuzo1RjJWIYhV6BitMvl8n7IWSKMWagEDAB2IgBFmABfIBAyyB9xLAg5QGcoAIsAEXcOBdNAgB/rDNhioHagxgAYLgaCasDKjlQk0Ef/yJXksJNw/uWwACcoT5In46T8LwgyeNy2AK2LYzGA529k4wGHhu5TYAvLs7cR4RTeJ3bYcDAEFVcI9wvmtujwA4CM+AWu93zaQTANooAKffsaWi3El/WHmDA2SgDNSBNvxPMIbR2gAH4AI8gS+MOwxEgliQBBbC+fHgnERw3stAISgGpWAT2AYqwW6wF9SBQ+AIaAEnwVlwEVwFN8Ad8ADIwCB4CYbBBzCGIAgBoSF0RBsxQEwRa8QBcUO8kSAkAolGkpAUJB0RIFJkGbIGKUXKkEpkD1KP/IqcQM4il5Ee5B7Sjwwhb5HPKAalouqoHmqGzkTdUD80HI1FF6Dp6GK0AC1CN6AVaA16EG1Gz6JX0TuoDH2JjmAAhoLRxBhibDBumABMJCYZk4YRYVZgSjDlmBpMI6YN04m5hZFhXmE+YfFYOpaBtcF6YkOxcVg2djF2BXY9thJbh23GnsfewvZjh7HfcDScLs4a54Fj4hJx6bgluGJcOa4Wdxx3AXcHN4j7gMfjNfHmeFd8KD4Jn4Ffil+P34lvwrfje/AD+BECgaBNsCZ4ESIJLIKEUEzYQThIOEO4SRgkfCRSiAZEB2IwMZkoIK4mlhMPEE8TbxKfEcdIKiRTkgcpksQh5ZM2kvaR2kjXSYOkMbIq2ZzsRY4lZ5ALyRXkRvIF8kPyOwqFYkRxp8yl8CmrKBWUw5RLlH7KJ6oa1YoaQJ1PlVI3UPdT26n3qO9oNJoZzZeWTJPQNtDqaedoj2kflehKtkpMJY7SSqUqpWalm0qvlUnKpsp+yguVC5TLlY8qX1d+pUJSMVMJUGGprFCpUjmh0qcyokpXtVeNVM1WXa96QPWy6nM1gpqZWpAaR61Iba/aObUBOoZuTA+gs+lr6PvoF+iD6nh1c3WmeoZ6qfoh9W71YQ01DSeNeI08jSqNUxoyTYymmSZTM0tzo+YRzV7Nz9P0pvlN405bN61x2s1po1rTtXy1uFolWk1ad7Q+azO0g7QztTdrt2g/0sHqWOnM1Vmis0vngs6r6erTPaezp5dMPzL9vi6qa6UbrbtUd69ul+6Inr5eiJ5Qb4feOb1X+pr6vvoZ+lv1T+sPGdANvA34BlsNzhi8YGgw/BhZjArGecawoa5hqKHUcI9ht+GYkblRnNFqoyajR8ZkYzfjNOOtxh3GwyYGJrNNlpk0mNw3JZm6mfJMt5t2mo6amZslmK01azF7bq5lzjQvMG8wf2hBs/CxWGxRY3HbEm/pZplpudPyhhVq5WzFs6qyum6NWrtY8613WvfMwM1wnyGYUTOjz4Zq42eTa9Ng02+raRthu9q2xfb1TJOZyTM3z+yc+c3O2S7Lbp/dA3s1+zD71fZt9m8drBzYDlUOtx1pjsGOKx1bHd84WTtxnXY53XWmO892Xuvc4fzVxdVF5NLoMuRq4priWu3a56buFuW23u2SO87d332l+0n3Tx4uHhKPIx5/edp4Znoe8Hw+y3wWd9a+WQNeRl4srz1eMm+Gd4r3z94yH0Mflk+NzxNfY1+Ob63vMz9Lvwy/g36v/e38Rf7H/UcDPAKWB7QHYgJDAksCu4PUguKCKoMeBxsFpwc3BA+HOIcsDWkPxYWGh24O7WPqMdnMeuZwmGvY8rDz4dTwmPDK8CcRVhGiiLbZ6Oyw2VtmP5xjOkcwpyUSRDIjt0Q+ijKPWhz121z83Ki5VXOfRttHL4vujKHHLIo5EPMh1j92Y+yDOIs4aVxHvHL8/Pj6+NGEwISyBFnizMTliVeTdJL4Sa3JhOT45NrkkXlB87bNG5zvPL94fu8C8wV5Cy4v1FmYtfDUIuVFrEVHU3ApCSkHUr6wIlk1rJFUZmp16jA7gL2d/ZLjy9nKGeJ6ccu4z9K80srSnqd7pW9JH+L58Mp5r/gB/Er+m4zQjN0Zo5mRmfszx7MSspqyidkp2ScEaoJMwfkc/Zy8nB6htbBYKFvssXjb4mFRuKhWjIgXiFsl6jBB6pJaSH+Q9ud651blflwSv+RonmqeIK8r3yp/Xf6zguCCX5Zil7KXdiwzXFa4rH+53/I9K5AVqSs6VhqvLFo5uCpkVV0huTCz8Npqu9Vlq9+vSVjTVqRXtKpo4IeQHxqKlYpFxX1rPdfu/hH7I//H7nWO63as+1bCKblSaldaXvplPXv9lZ/sf6r4aXxD2obujS4bd23CbxJs6t3ss7muTLWsoGxgy+wtzVsZW0u2vt+2aNvlcqfy3dvJ26XbZRURFa07THZs2vGlkld5p8q/qqlat3pd9ehOzs6bu3x3Ne7W2126+/PP/J/v7gnZ01xjVlO+F783d+/TffH7On9x+6W+Vqe2tPbrfsF+WV103fl61/r6A7oHNjagDdKGoYPzD944FHiotdGmcU+TZlPpYXBYevjFrym/9h4JP9Jx1O1o4zHTY9XH6cdLmpHm/ObhFl6LrDWptedE2ImONs+247/Z/rb/pOHJqlMapzaeJp8uOj1+puDMSLuw/dXZ9LMDHYs6HpxLPHf7/Nzz3RfCL1y6GHzxXKdf55lLXpdOXva4fOKK25WWqy5Xm7ucu45fc752vNulu/m66/XWG+432npm9Zy+6XPz7K3AWxdvM29fvTPnTk9vXO/dvvl9srucu8/vZd17cz/3/tiDVQ9xD0seqTwqf6z7uOZ3y9+bZC6yU/2B/V1PYp48GGAPvPxD/MeXwaKntKflzwye1T93eH5yKHjoxot5LwZfCl+OvSr+U/XP6tcWr4/95ftX13Di8OAb0Zvxt+vfab/b/97pfcdI1MjjD9kfxkZLPmp/rPvk9qnzc8LnZ2NLvhC+VHy1/Nr2Lfzbw/Hs8XEhS8SayAUw8IqmpQHwdj/ME5IAoN8AgKw0mVdPWCCT3wKQkb+rXP4vnsy95R0whwCNsIn0BcC5HYCjsDWFLQ3WKMixvgB1dFRUMFnEaY4wn4EFobTA1KR8fPwdzCcJlgB87RsfH2sZH/9aC78R7gPQ/mEyn5cbqxwEwLfQwc454tropVVy5Z/lPzaRFDnqunSQAAABnGlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNS40LjAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczpleGlmPSJodHRwOi8vbnMuYWRvYmUuY29tL2V4aWYvMS4wLyI+CiAgICAgICAgIDxleGlmOlBpeGVsWERpbWVuc2lvbj42ODQ8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpQaXhlbFlEaW1lbnNpb24+NDE8L2V4aWY6UGl4ZWxZRGltZW5zaW9uPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4Kl/XR7QAAIpRJREFUeAHtfQ9YVNW69/Y4KChDgqKmGRl6JZMR8cN/ZQV0vqNZzWTW8djQjU6H8aknlXOPdbDsJlRe7JSiHR3/NZRgIqiMf0LNgQT/gFxABxUo0CECFBRsBprRGQ7fu9bae8+eYWbDIHnvp2s9PDNrr/W+73rXb71rrXevvd+hX2dnJ0MTRYAiQBGgCFAEKAL3HgK/u/e6THtMEaAIUAQoAhQBigBCgDoB1A4oAhQBigBFgCJwjyJAnYB7dOBptykCFAGKAEWAIkCdAGoDFAGKAEWAIkARuEcRoE7APTrwtNsUAYoARYAiQBGgTgC1AYoARYAiQBGgCNyjCFAn4B4deNptigBFgCJAEaAIUCeA2gBFgCJAEaAIUATuUQSoE3CPDjztNkWAIkARoAhQBKgTQG2AIkARoAhQBCgC9ygC1Am4RweedpsiQBGgCFAEKAISCgFFgCLwGyBgM9VVG41WhvHyChgx/H7/36AJKpIiQBH4/xUBS2tzi5mRDg+U/k9vwuInAabUmH5iSbHZZClHJFGbTS7HwlKuglogc1nrrrB3XO6kuSm32Swmk8VNpQfFYnIsdfFjN0x9+XibB/L6gFRMpe7E3w6vULa4HIdacRMSCu0+bypS+W2fAn/RFxttzuQ3ijJQld/2mNTbGnhLuRaEqNwKab9wQBsdsPv5aYeVjx1WTjvwTND2FxafPdvgrA+97msETOWbYb2J2Vze14Kd5d2xhpwbFlxX7kSL6+bSVkHZHc1W7cqYOnbDl2W3NZnuqMb/WxqzlabG+wQMHz16+KaSboavcmc8jLJqZyXoLsz3YVfEnQCG6X73tiISPzcqWa0/Qs3lm13WYzf0pLh3XKIiu1bqNy708/PZXNp9D7vyCkvE5Nhu1gJpnc2z7gul9yovplJ3Am+HVyhbXI5jragJCYX2IN/xKyEqrtBVOJFfP5XBemNtN52qPLy0omWv6WaHKzbrpT27lK9ca2GYgOgRC5cHKRYhR9+wsyQ2pOBUsysOWtbHCJhuwgHMnUh3rCGXnfn1Glpcf7lDfXWhgvkaWjxNVpfzwAU9LWIRsOgTY9dBXhYZFzLMRxwWq+kaEFy9htY1YV6cy6Na8ZMI6WvZnUqGIUSl6xVTl2ojUwpzl0y3t2EplcKF0V7gkJOGa1uaLIy3Z4ehveNyaLj7i0F+SHE4rO2eVJRCTI7vuK/PKE2MzxBRCX1eKaZSd43dDq9Qtrgcp1oxExIK7UG+P0dzQ3PYpAzFY0yKTNXfbGMrfTmi3n6jGeHL8G0JxFjOJcfC5ZC3v1O8Pp0leC/p7McLS7KLf/j0m/B9SwYLqGm2bxG43cncY23uWEMiGoW/qW36k8Xb37PFVUSgp1Vhb/zp4Pxb0gBq0R4i5z0IrUuR6pJclfgG7KHcXpJ3dxLAeQAg3msg0tyPcWX/oxlD6f74GMVkSP0mr0gtYE+IbA1HtqrVu4vZS0tD1vr4KEQEKSopNdf1bXjvuBACtsrcnaAGbiJKoVqxs6DGxV24rWFnUvzHX+uBYfHSvySlFhAaS0Pp+hUxUZOjIMXEr8mtFNy3udTcjRykCEm21mMZp3fnXELdt11L+3i/em/VhROF8S9ve3qmev7LGWl5VzlS9G1pMKhXps+fuW3+3G2Llx85XuXgWzWW/feK2K/mz/0qJnb/t2UNxXuPp3xRJlARS3KjUjOMjiIKjpX69ZusiEk6LOwar4Eb3j6GxU0rjDsTwuqJ6cDr75RpSarCwLPFzScrzztRoEvT2QMHY6LxE4QpGaqki1UOiN4o3qONmYJqo6fsSfi0us6lwVqqvkw6mLD44LrDVsZ6Cx9FBM/lPABoQxIYtvQ9p9lubSwtWBWTHh2d/kI0SK7i27U1FK1afPjLghuXcpFi0apj7/9Vm5B0uVlgyDdKj0FzyQfacYd6LOqv9a6eSzUUZakUk7FpTAazL6jl++h+NtkaUleoVmzOra3MTVIpYL7AfI7fzM16rJXTR0NpVjzMLUj9JkfFJOXW8K0AoaV0/3o0a0GQQrVmZy7f14aCVJVqRW5lTW5qEtuMIj63ll1OUBOW2p1JKsSnUMSv33+uWeyMx9ZauXMNzAOkBnCsWL+zspVFtQ8baijCOtfU5m6Gta6fKrUcQ+G2j6QXWWtUAA2an1Exa3YWCdBxy9hcckS9Vl1cbwHl41WqpNQi3BD7UbpzjUoVn1VOTpvdChGykLwISk7EzRUVOzadKWm6BeV1eScSV+pOnTfs/jhj/kz10zO3xa88ccnB3m6dPahbDEvf3G2w9KXsusiPMhJra83+bG/My1/BX+IXZVVVVV9+duTbMocFkG/dnS01FGxWxcTvF5gWKTlcwxmMpdYtziJV7u0TVHKnjLsqS20ubD5pUJ23cfmKNWDM3avN95zLmMqzYMRXbGZ3LlxsK0pNQiNeKbAdjr6b784eJ71aCbLkKSUOHOYSVNolRSbqrEBnLImEqsiUFsRTnywjdLLISFSMklKDqxxE9pKrs7MEa4jE2htglmkNjtI7O816OSLiUqTa2NnZUqLhrmWsmgyTmEN43WjuSo5DW6bLLzy0PnzOsVYoNV1WQp7926Scw+ZVWy4TltbSAr42mqNMPtJMaiu/2cPV8kIgs/WMidRzn65UqkhfxnYtUi7n+pagreZ4uG9XvH0PS9dWxE2om6HhlGe/jYVK6bYw1cnt8dvCpLs2FvLVjRkqKMlem5IdJt2mVJtxRWMGIkN/CsWuKJwJk+YcYpH5GbPg2qhUQhYWdqHB2mkuycJC2pAQo/7DKCwkSl8DdmQ8qcBy4tZcqqm/xTff2Wkzm2+Z0ZyA1FamYdsNC+MkS787io3NVLKLbYvo88S3z6FMVkYF4YVP0pdtS7NAvieioi45WUtnpz49jrONSM40ZDn1SE+x2WQscZhB/MxJyGF7yOuKM/W6RL4VbuYz6hIy9Vs0nAoMP/NkiQYsqCTFZTuROaTarOcsm9MAfzuvUUSZFn6lEqw/zLLqvm7ISedItGCK9REsiAcgkhsEGYukGCNpKKWkxViSgvsdV8Gjb60gMjOrwdLFhDgOFJps3HruAiUn4rINqbAobSpF84DkyRoV/dJWbrFKO8Ou72073uIWrhmb2NoZh34iCpt+SuBWPI4REb/wjx+dWoRLEVviAeG5HEpEcBapEkVPRBl3VdxgsRabXNLioCRWXVgi3Hb5vLk6nVh6CVnIgMusJwOHR5wHoEcZpkdUmIjXwIGFX8GVKRUtSKPqnGSkH9n4Sa0c7bJGvZqUN2F+a1MhUVpHroVCe8fV2UKcDHVhPRFWnYOXHrkGWu+SrIV4fUnOx8TWarKaLNPkY2JzoYYUKCvM4po7ynFqxnxZBcb90vdo7TVzTsBrBaTH59l9fev3cG29QqZBwleVeKG+eeYrsuunVQKoTReIW7BqD9LW2vLTupfIjEot67KsQ71D11p0ZNlNzCF7m7WE9Qnk+S78L0fe3wgWJw3FTUhUBye8wcqIE1Bbk4+30hXXWIqWfLQ3R12oLLQ7Aa26NLzdfneURaaW9QkUP4LX1qQj2/OBfRVIhrWpeGkYbMZp4FiwToDG1mku+zsq3BamrATnAKfWo4ncBg/lYVlLV5zM2H+p0mB3CKzVB3C7B3bk4ylsvrSD+CLKRrgmwrHMsjMVrU3G1u+xQEUK9jmgjSbcF2l+mbHTQ1FEQ/tnk45s/Msy2T6mx6ECeOQHu4HYbOKHTJ6sb0KdqMhMsM96ewMkZ0zHUz05n536hcRZT9BBdXUmnmiyZfkGNPNgWViGdVJqkEpkzQHJiVo9asaoT8C1KYXIdvMTsWnLEkrqodJarSN7YZcbFSCF/hTidUmpxh4O4FxNuNV61G4fNsSLUiZmVhjqjeZu+sj3AivS2VSiwV2UFxq7YSQNgRMAO2OiABZ7Z/HCK44wgkaQxFESEKLs+S1psFUTJ4Dk4XJ70S+ojtvXoz+6AFc1e/BqNmPPyVo0jNamHxNmoBVM9RVa0E5+hJ2GGdrzaDWzVR44DFXwp9xwGa4dk5gtCQBhmYQlIjiLVImiJ6KMSBUs4IXIt41MIaYoVJLoLSwheeLXCvItKdj2E7ntkx24SLWLRd0Rwa5X3T8OQHO7+yTTfb4kxN8bCIOfnoumfF7uZadjCSs+qcsrPl3eYLHBEen0jQa9TqcbxdjExHvAJZn5rlqdWaKaPooI9PG/D2WMLl9LlAzCTze8B6NnHKaKY+vgS6759LXZ+Cmy9/TXPtWggUo7/qOJEdPBQQ4wiCT86Gz49g2PB2KiRxfKkxbAsxVzxc/tbZWVR6AwYkriqxPwA+sBEa/K4yOgqOVktaUqp6yVYfwXPL5iPuqaxH/M0n9GB2Ehrj4cVKrUavLgDZTE/JVzgjGxJHzRag0aIW3ZZZDqlBx4fzNYHFrhNHBtQt3owDE7frf3fzBiwjQo21B1AVlhR92JHwwMMynm4eD7eGu7clADp4SShYee/j2LzIMvfzIJcekaDa31RzRAKVHsflYRAkVgr//nPxJhaCQ3yRk8nAMW5iXMKzlcwwS8EZW3Y8L97Hn/kN+vfFGTPnoaGjyGqblxfEPF6ldyF4Z+PeWFsxcQ4JaqY+gh0KT1c5Wz0YRhvMcq10yaBBntJcFJ5tQ9mrCIkCGB0iHTFUOg0qC5hOMdOuoKUV+YtyeGST0VBWzCVH5IA4/E4KZz7QK2j4tWJIHV+1mgjz2ZTbKcre+EBqJOhCj+BIwuZr2gvfKykoZWBPl01caSfJ1OPsrGmI6loZmnTvt0dhCaebAsfJqBzuTSsgv59UOWoFv5fChqRhr66pvIdnOLLjOW8i0fINPW7v8kfBRUSoKjlhD3Fwi6Jp9hM1NS1IWfq0aRgZL4DPdDVDetvEUAFH3QENt0XKZm5YKQoFFSb9E+8r3ISSQvsASGK5MTAEtpu+lGT8DBzY1SxCNYtu8qwp2xFexCd4oJi+dIe4YwqzPD9AQlnrhrJmKV4vVpGFbfMYnHZ8LbCq0nGm8wlu931QPxW1vlsx5EwygJHJeYOgUyxQcvtVnqvt5mhqfNSRnzHkVrX/8Jz/5hwxs+kBNJrmxJhBxmHWctXXFuPssaUteqng2BiDIuqyQ+XvjJ+sDbCA70n/cm8p4/yDguHPFly+YA5p4mpyeVnrLz9POC+cZtrl9XlU6MhBOqLUyaXIYeiMiVy+a+tPDlZ6L8RVXwhEs6e9GiAVnwTsDac3p9nh498idJtAWEoeHUCUSpjV2gyCYs6EqLsrBG9EwHPBY8s7tMxOhxeJPH9f2DYN5ntZz87+bZzM+opLgs9uUanvViMcresnbYsPv0nDzY3pHAh5+N0P0TE/D0XTJIJeLARE1+UFDrPTVayaSlXfnZyITzwyaoR9k7A4sQNNcmJD40Tkpzl20djHfwordLzmz48WDxrEejrny3G6qGvRjpzRj5JjvQo0xmaKgDMg/Mlp8/o21vMDK41jd4NCeTYcY890fykNJSigpbdtYexpXjZA+gXdqehoQ9N2fzcx0QgtpguFpZUndUW3tcB75FiXJJ4OkdTBE2tvNLsmKwhWG+Nvy+Qod9Q5IHsJsVOAmhkxQRJ+C9Ql11qDKE9GXI2wuHMky9p6LsOuIctivZvwn6GPR8dmcnoep+NslemRrISZQ8MFfOThmuiP+Whs+NY9K2pC2dm7YUdm35sgWKhYvkUbBkWMpLMQaLlQtyxnL0Rlwk8N0XzA3l6pgREeBdpeFLvM5Evjk7iK9kJkfOhYlrvxbkvINnx84bsFMdv7rk3GVtnn11END0SUNEnjx8AjtbLQbRPpLVcsbYAH5yS+Z8kt35Cdq3MnoADmkudN4rMiZNv25fxeo5oYz+y3XQP+WCp4J6iDCPQU9Q4om7ZqaF8wbBSIaPGAdLWuUVw7XmcrxS/fMvaXljOCaTEeVMHex8DBkf8aD9RVuZfDyzzeUQubclTrCbbxGcS5HXyfRiCMSUcWvzbvTztDg4en4ksy5vS5r+HwvCvSoy0YjLF0YKJkOPJfbRSYA8yG7D7tr2Dt1sbdJpkpX4uZc2bd1i+YwAr6iCZncMuLznXJbK+H5+M15avC4tLW/oUGVcQkpKAhKBHVPRNhgrFwoJhmnkklyplEfKhw2SwCrcG81dN9nhUIxX4cED+1u54xC4BWs3WcnfxKcCJob4BQxi54Z0yAABr6McQYXLbMjYAIdy3K6PL5xDiKU7CAsYsGsT6kYHd+pbGOnUF8Hdsu06eN3W/EM6rKYRIbAm2qz8WktYA4IckcF7v2Qwi0zAwyPdtYDKA/ARwpklR7JrCJm1sejUpvVF35bC8PT3lg55OHTCM689vW7fq/uzse+nvVTZ2sGwr0vB8mdrM5I/32ly34eifXx47do4i0CCH14YA5839hy3MM0VqC/Bj+B9sReiiJ7Cz9BgV33syWwaex+6rWOTZCCX6/odsmhzk16XvEwpgzq9dt0HsTPGBUStKYD7v0EstdE+8fzQzJNPHspjMXywvR2JF9eOZBDmxaZsb5KrtZewuZqseL9xMxZ/sE6rvT5UrkxITkH3246pTxpiRdrDFEX7KBk0DBgiHx1p7yKvkygjT0UygY/hs4AteRdNrcWHwERkCbHhSKYnQuDkqgcoObUsvIQ7FsElyUu8JP25+3qYzezi1i71i3jKb+KkwRJJfzQDpQM5GizA7g0L5OGse1viKXnDYRjeHERwFqnqDj0RZUSqeEUdM67UdqRwuPKPeBO996E9dLbVdC4nDbJxyqn4HNuBrAcXgoZ7QH07JJaG8lOVv4YsfGfHa+9oLK21F4u2J85drc37bG/5bJXd03dqoudcpotH0cFiZKI+Yzk5omQa9i+FOw/Y2LtLQ+9HtyFwGJj7SRRP21pTev4aEzJO2nMdeF63Gf6IE1Nca4JzMCYsNHBoPYye0V8ZvTdpIs97o8Zw8TozPti7/jvkLlcb2phJ3FLR1pjXzTEAK8Z6EzV54pRBFcqDbCk/gWzmviEO845lEHzdOVgEjTplxXVwIna49JVNfJI5c3zb6S98rrcwzLSYILhfh9NoLnXcRJtxY5GBedSOTGMRuvkaeJ8PqW06V8fM4m5uGnMPvrOB+cPfn0UPccADeFuh+7j/t+/teW/D1VVxVY/pJgQyHS1nK7a8zzDLJz4TDiPKJ68xTwRPY86dQQWDRyJjkyiyX/lPu7G1XyptvM6MCJYK9347+4T/C75KrWH3uW+ZetSX5ePv76UoXiZkiG2cKqtjZnN9bMiNf3M9o0hIlBX1ejYJm8B5U3lR8Y1BIe+s3fHOWk1rQ23Rge1zF6/Oe3dL+ZsfYgKZ7lhuFKcCHCGXFpxnRk3iAbzpEhTzL1eBGR47Wpbg55BI0tXLP2CBXT/YM/nETH3CglCy6h2O376a0QtJ+6IhoTyclxCH0k0fzT9cBqq83DrLEvxcBS5sBeuXf5brk7Dp3zG/G0ZcJ/iQzotNZNI+yM464GfOgvL4V2ehWvHWBfw42yOUnJkcru1384zp1yaoihgZ5EsKvT7f/8aT9lFuP3viZ+b+B3wtjXVAVtzSiqJu2VR98mcu6/Tt3paWzCakFvQrHsR2bPXnuPE1/+IW57Xz3FZ1MwQiyoQx59zY/JLZ/HIj7JtrtYUUznnvaGUys+XdrL3aMT6HoTL59ejebed9dBLgrJ+La8PRldHRM97dVQ51Em//4PA5r8IBIkrkoAZnu3x4wIVvESIjn2I9AMa0f/uXSJ7fQJEb3oFeaCMcPfkx+NSv1tiPJZoLYsdNfWLG1NNNtp7oQOSg5sRTpX7j0WuExFJTloIehjEBg353vwwdSremldl/Tqa56u2nD7z9xwPFTR0jHkVT58jb+RfYe0hL9qpjF4kU959EpTGTpgJJ2uIv+F9FMpXvTUY+gHz6WH933HcGlp6AJj407vTH5ZKHX14JmatfbQAfavQCeBbgkPwnhsP1jQ3//IlFlbFc2HsB7dPRDzzk7z8ZraFtWWlcWJ2t6uuPr57Xtd/irGnUg4Ph9wCe+dsjk4Cw+MRf0Q8IegfPwk8GPj26qUBo1u0XtFXYA5D6+QwJRcZmy9ZU82dgzQUHX3zqeNxTBoeoKaDi06hJsTBZis+/txz6ErTo90SJXoniZTJjpqA+arfvKGd9U1vu9o/gTvnyTS8ICIYqT2eTXbQwZzGsnBH9hOzdcuSBSfxHBc9R4RcI4K6wMwg9I2T0mm+KeI6CNbFTn3hi6hp7CV/lkJGOnCqDAu2OvWhJQclSvm7lapLt8uklRftC5FPRrAdgqtmvRieoTPdG6FlDXVqWiPZR+vAs9IaXvRe2hmP/uRQG4aKXb7BH4ATOUijBnVj9Siz0S5Y8LwTbu3jrzsreBkpY1NYVuXVgoCjd+nb9qVr4HjxQIhn2+DzIWb/JqEY1OJ36LOvPMUf/vLaG8R0aOhKKaj/fhZwBSG1VhX/7zEjyzp8itgTzDd/3p+86TVRoLU2bi4cYCRHBedi/9XIIRJQxubd54bpAuieitnP/Ha79Zz4Ps0e/LjZ2dR7DLHtxKlrPTbXlBQUFlQ3slHZgcHfR9V1BdyWCVxMFJCRYCL+Gypay4UPo7VYI9kP7PK61GjKJDvIEdU6OVp2IX0RmmHQUxOKYesVlrkgn8pWJ6nR46IAWCJIiU7R6PnaGb4mEYcgi5QmafIj6ykSLEaRI4E5Xk3eQ0TtTwCiuuaMcXjzOOEYHoEgB/Jew4XTGFi0bB/i3UqzbzX1sCM3W5C322uj3z+HalnX4ZVqICVz1j8MJbGgASEt1DhHEzTqq1MRFZspTMrVaDXmPmLwB7qitC97fBhYIP8OhGSz4guFmFRKakOjQdOmA8SQKEVTUkqAJsx7FAqA/BRsdR969V5AQwaZcNixQkb9vv35HIgkHQO//o0QCChBv/g7Nd3EkCkBKQgRR6IFCTV7Xt/20n40jwLGFbPweIlDmb9ec3LjmQByJIZRui0vHtm4uW0q0ivpue3rx9hWEPfXDHBs0y4YIcgpjVdAHF60AAZCNdmvulSheZif7jjFM0RSNJpGbMxAi2M1s6jpknUb8Ii2e9Xb5JGflJpdSnZmjzVTHkUC4uEzoh7maXRZkcYnpmekJrA4yLQ4CFL4mTWSRICPysnRTfiI7aZelZKancOq7jA4wp8MOCUmmhPmdnEAuUEFkXIq+xdp3DbGBBsIwRfE+thSmID1gDBJSNGp2ejLLcqC/4oxdddaRgAc4GE6v4AdBXAhPhjPdoORI7Do6IHzOnow9p1e9xMYB7qtFRm2uLiZLX/Rbh1Dta6R20yFc25R7iNS+8JZ23Uf2WOgXXEQHiNoSCUCDMV2WrE4hUSYIWBxAAeEhbnEWqRJFT0QZkSqAA2+L3Jv8ZlG1hduuME/Ggo1rgC4ns+HQJThsQMZdOg2Zy0sPQgQrcDyvUq13EGTGQa5CJ8BMQlTjUEyPQy0Ep7GTFo0MTolau7HaxfaOCwLP1OxOjmVHgq/BhRkndw2caCpUs0rIyM8YNGU6PiSUJ2RyXGKad5Fj7weEBQpDBIkToOSmB9j9C28VcJFlwPXLvvdR3C3/p3y/GP3AAEnWloz3UUAO/tuU8JEW/QLBjMMNXL3w21klY4XQJ4Jex6XoYHBcJmfezt8AFtjRhOA7DDdWSmhCqEBEB6dOGAvj0LbNOgGdnZX/hTbg1L/vR0sRJC66j+2+qSKX291JXF/2Rp09ls9sOInDArmQP0XxGRxQSnwLpYbH8Ocd6EcI+O258WgKCT7kGKEq7MDGHPCKudRU9qFCUCvd9WEWGwForsCOi+pnXjrLYyYxirvW2n/8ANf0QhSnBXybDWrWGyezQZ7ORtiKzqauQ8Y6AXjWC8STrLWpJJGc+rFTDna85AoOjhZ9pmOlPFPPzrwK/DMG6hKOlIs0VmrYVahCK1xSIhPw7s7XChWxNuU7rA7L1DptMlEnsbClDxsiooTbMKgh0keoNehS7PcsyBtIN3CjL8LI6cytUjCY7I2Qc/SviBAhRJAXR8mJ2EWI4IxU/jdO4I5le4Fdt9byYsEPpaAbmH3lXNBrZ2dD0WkVe5+zPvqlPaveQkGDybl2dr5pUVuycqHdeGDBq0pE3h5vPyI4i1SJoCeijEgVrEJILSUfuy6mttCchHkCCPeDAQz/8wB6HPrlcgrwGDpl+sE1mQl36NPSXHmxDv2omtegseNJUGEPWu4xl6W51nDd7OXlNxyCc9ATEktzg0ki9fd3GY1hMbWaGR+pj7eEfZhiAvYrRq9BfkMDRgTyTxqJgiI6dJHDdslSt/iR7OII2fHdT/paDIsfOVAcMeXk7sdNP11tMXcMCggYwz0G5CFoa75We9Us8fEJCPAL9B/AyTFeqPjF54ERDwcybW3/kvh6ezN1MWOzL4bIjuc8yT9I44WgTBeVmmsrrxitViszdOz4IKeuOXC64O1jWEhzXTR00sLpUkwHJ1IPL011lfDv/jqszOCHxg8d4vTQgGlvrG03M/19Bg25P1DwwLPbNizXq35sN6OzvwF+I4c8OMq7y/M6sNXrTcb+Pn6DA0ZIu7TbbQNCgtsUBc/p4R+aSXwGjR4VKFTTs9kkVMhVHiyw7jqa+oOGjg0JcnoUZaqtrIcjYD+/oSNGdZkVrqTxZTZTQ7XhOqwnIx4KFrdrsOzaGoPZ6uU3dPioQPR4AP6Tm8km8Q8UD1Fim/KkIV47YUa0j/CaFLzuIZEMChjd5f/KiTIKWxDL91xIT1G6sDX91U9a/rL39cVTBpN8/GGVMshyqbbNKhkwOmiYr9CYkG6WuqoWNMpS38BRfvxMa66pqzf7hEwaxrRB8PjvfH0HVG1NX8RJdtknEVsCowVL8vHxGz7K1bCK4CxSBafs7u1TRBmRKqd+daO2EzV3aanc6fPIK/ALxC25KqcZxZF0/33HnYDuVbpLKGyWW621F1RzTtSGyHQ5Tw5hnQCZbveT+LGxB91sK9M9OR/eARj+dekfH0VD3b57+TfJWWZm3uNFX0xxnmgeCKakFAGKAEWgFwh0WNraC1L2/X2bUegEkLyH4izqmVu3XmGeWK1Yu3AM8N44X7jgueJWhll5XKV4kLsR8lDoXU8O/wQXfmZj119Gx6Yx8JNBKwUv1nrad7qDeIpYT+nPb/v6z5+h9/4gWAyhbGPa4RMGzvPkOyX8jyMvZlxpejV8A8QNtn/fgt64YXw+XyGj4+c5nJSDIkARuD0E2i4vCs3BqxAzwIsckPVmZcNKeMs/Cd76ek1+QvbUFL+IEGvx92jZDHoj+lnqAbgfJf0W+dSl8D4gpMQ/34YHAPz9P/zwQySHpr5G4Nem5gvXrI9ETfxHyuMjwJ39180mQ2PgrPHR0xxOXHvWrM9jC4NH9G+t/clUfd78y0ivCEXIB5uenzWKe1O9Z1IoFUWAIkAR6AME/mWpvVDf+dB9yg/m/ft0dLLZdv264eqAxxSPBN/nyUMzrIp07PhnZvVvvXa95nx7g8HmHxEQ8x9PJakm0EMAkZH6ta7q+2teMx5//auchEektxXlRx8HiOBMqygCFAGKAEWAInA3I3BbHsTdDAztG0WAIkARoAhQBO52BKgTcLePMO0fRYAiQBGgCFAE3CBAnQA3wNBiigBFgCJAEaAI3O0IUCfgbh9h2j+KAEWAIkARoAi4QYA6AW6AocUUAYoARYAiQBG42xGgTsDdPsK0fxQBigBFgCJAEXCDAHUC3ABDiykCFAGKAEWAInC3I0CdgLt9hGn/KAIUAYoARYAi4AYB6gS4AYYWUwQoAhQBigBF4G5HgDoBd/sI0/5RBCgCFAGKAEXADQL/D4BaqFLDMQVOAAAAAElFTkSuQmCC"
        }
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import Expectation

client = MockServerClient("localhost", 1080)
client.upsert(Expectation.from_dict({
    "httpRequest": {
        "path": "/ws/rest/user/[0-9]+/icon/[0-9]+\\.png"
    },
    "httpResponse": {
        "statusCode": 200,
        "headers": {
            "content-type": ["image/png"],
            "content-disposition": ["form-data; name=\"test.png\"; filename=\"test.png\""]
        },
        "body": {
            "type": "BINARY",
            "base64Bytes": "iVBORw0KGgoAAAANSUhEUgAAAqwAAAAp..."
        }
    }
}))
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.upsert(MockServer::Expectation.from_hash({
    "httpRequest": {
        "path": "/ws/rest/user/[0-9]+/icon/[0-9]+\\.png"
    },
    "httpResponse": {
        "statusCode": 200,
        "headers": {
            "content-type": ["image/png"],
            "content-disposition": ["form-data; name=\"test.png\"; filename=\"test.png\""]
        },
        "body": {
            "type": "BINARY",
            "base64Bytes": "iVBORw0KGgoAAAANSUhEUgAAAqwAAAAp..."
        }
    }
}))
package main

import (
    "bytes"
    "net/http"
)

func main() {
    body := []byte(`{
    "httpRequest": {
        "path": "/ws/rest/user/[0-9]+/icon/[0-9]+\\.png"
    },
    "httpResponse": {
        "statusCode": 200,
        "headers": {
            "content-type": ["image/png"],
            "content-disposition": ["form-data; name=\"test.png\"; filename=\"test.png\""]
        },
        "body": {
            "type": "BINARY",
            "base64Bytes": "iVBORw0KGgoAAAANSUhEUgAAAqwAAAAp..."
        }
    }
}`)
    req, _ := http.NewRequest("PUT",
        "http://localhost:1080/mockserver/expectation",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    http.DefaultClient.Do(req)
}
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
    ""httpRequest"": {
        ""path"": ""/ws/rest/user/[0-9]+/icon/[0-9]+\\.png""
    },
    ""httpResponse"": {
        ""statusCode"": 200,
        ""headers"": {
            ""content-type"": [""image/png""],
            ""content-disposition"": [""form-data; name=\""test.png\""; filename=\""test.png\""""]
        },
        ""body"": {
            ""type"": ""BINARY"",
            ""base64Bytes"": ""iVBORw0KGgoAAAANSUhEUgAAAqwAAAAp...""
        }
    }
}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
    "httpRequest": {
        "path": "/ws/rest/user/[0-9]+/icon/[0-9]+\\.png"
    },
    "httpResponse": {
        "statusCode": 200,
        "headers": {
            "content-type": ["image/png"],
            "content-disposition": ["form-data; name=\"test.png\"; filename=\"test.png\""]
        },
        "body": {
            "type": "BINARY",
            "base64Bytes": "iVBORw0KGgoAAAANSUhEUgAAAqwAAAAp..."
        }
    }
}"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
$json = <<<'JSON'
{
    "httpRequest": {
        "path": "/ws/rest/user/[0-9]+/icon/[0-9]+\\.png"
    },
    "httpResponse": {
        "statusCode": 200,
        "headers": {
            "content-type": ["image/png"],
            "content-disposition": ["form-data; name=\"test.png\"; filename=\"test.png\""]
        },
        "body": {
            "type": "BINARY",
            "base64Bytes": "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"
        }
    }
}
JSON;

$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_POSTFIELDS     => $json,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json; charset=utf-8'],
    CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
curl_close($ch);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest": {
        "path": "/ws/rest/user/[0-9]+/icon/[0-9]+\\.png"
    },
    "httpResponse": {
        "statusCode": 200,
        "headers": {
            "content-type": ["image/png"],
            "content-disposition": ["form-data; name=\"test.png\"; filename=\"test.png\""]
        },
        "body": {
            "type": "BINARY",
            "base64Bytes": "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"
        }
    }
}'

See REST API for full JSON specification

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/some/path")
    )
    .respond(
        response()
            .withBody("some_response_body")
            .withDelay(TimeUnit.SECONDS, 10)
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "path": "/some/path"
    },
    "httpResponse": {
        "body": "some_response_body",
        "delay": {
            "timeUnit": "SECONDS",
            "value": 10
        }
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import Delay, HttpRequest, HttpResponse

client = MockServerClient("localhost", 1080)
client.when(
    HttpRequest.request(path="/some/path")
).respond_with_delay(
    HttpResponse.response(body="some_response_body"),
    Delay(time_unit="SECONDS", value=10)
)
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.when(
    MockServer::HttpRequest.new(path: '/some/path')
).respond_with_delay(
    MockServer::HttpResponse.new(body: 'some_response_body'),
    MockServer::Delay.new(time_unit: 'SECONDS', value: 10)
)
import mockserver "github.com/mock-server/mockserver-monorepo/mockserver-client-go"

client := mockserver.New("localhost", 1080)
client.When(
    mockserver.Request().Path("/some/path"),
).Respond(
    mockserver.Response().
        Body("some_response_body").
        WithDelay("SECONDS", 10),
)
using MockServer.Client;
using MockServer.Client.Models;

using var client = new MockServerClient("localhost", 1080);
client.When(
    HttpRequest.Request().WithPath("/some/path")
).Respond(
    HttpResponse.Response()
        .WithBody("some_response_body")
        .WithDelay(TimeUnit.SECONDS, 10)
);
use mockserver_client::{ClientBuilder, Delay, HttpRequest, HttpResponse};

let client = ClientBuilder::new("localhost", 1080).build().unwrap();
client.when(
    HttpRequest::new().path("/some/path")
).respond(
    HttpResponse::new()
        .body("some_response_body")
        .delay(Delay::seconds(10))
).unwrap();
use MockServer\MockServerClient;
use MockServer\HttpRequest;
use MockServer\HttpResponse;
use MockServer\Delay;

$client = new MockServerClient('localhost', 1080);
$client->when(
    HttpRequest::request()
        ->path('/some/path')
)->respond(
    HttpResponse::response()
        ->body('some_response_body')
        ->delay(new Delay('SECONDS', 10))
);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpResponse": {
        "body": "some_response_body",
        "delay": {
            "timeUnit": "SECONDS",
            "value": 10
        }
    }
}'

See REST API for full JSON specification

Distribution-based delays add realistic variability to response times. Each request samples a new random delay from the chosen distribution. Three distribution types are supported:

  • UNIFORM — equal probability across a min/max range; use for simple random variation
  • LOG_NORMAL — most values near the median with a long tail of slower responses; best for realistic network/API latency simulation. Specified via median and p99 (99th percentile)
  • GAUSSIAN — bell curve centered on the mean; use when you know the average latency and expected spread (standard deviation)

Distribution-based delays are supported on all action types including response, forward, error, template, and callback actions.

Sampled values are clamped to a minimum of 0 and a maximum of 86,400,000 milliseconds (24 hours). Validation constraints: UNIFORM requires min >= 0 and max >= min; LOG_NORMAL requires median > 0 and p99 >= median; GAUSSIAN requires mean >= 0 and stdDev >= 0.

// uniform random delay between 100ms and 500ms
new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/some/path")
    )
    .respond(
        response()
            .withBody("some_response_body")
            .withDelay(Delay.uniform(TimeUnit.MILLISECONDS, 100, 500))
    );

// log-normal delay (realistic latency distribution) with median 200ms and p99 of 800ms
new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/some/path")
    )
    .respond(
        response()
            .withBody("some_response_body")
            .withDelay(Delay.logNormal(TimeUnit.MILLISECONDS, 200, 800))
    );

// gaussian delay with mean 200ms and standard deviation of 50ms
new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/some/path")
    )
    .respond(
        response()
            .withBody("some_response_body")
            .withDelay(Delay.gaussian(TimeUnit.MILLISECONDS, 200, 50))
    );
var mockServerClient = require('mockserver-client').mockServerClient;
// uniform random delay between 100ms and 500ms
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "path": "/some/path"
    },
    "httpResponse": {
        "body": "some_response_body",
        "delay": {
            "timeUnit": "MILLISECONDS",
            "distribution": {
                "type": "UNIFORM",
                "min": 100,
                "max": 500
            }
        }
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

// log-normal delay with median 200ms and p99 of 800ms
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "path": "/some/path"
    },
    "httpResponse": {
        "body": "some_response_body",
        "delay": {
            "timeUnit": "MILLISECONDS",
            "distribution": {
                "type": "LOG_NORMAL",
                "median": 200,
                "p99": 800
            }
        }
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

// gaussian delay with mean 200ms and standard deviation of 50ms
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "path": "/some/path"
    },
    "httpResponse": {
        "body": "some_response_body",
        "delay": {
            "timeUnit": "MILLISECONDS",
            "distribution": {
                "type": "GAUSSIAN",
                "mean": 200,
                "stdDev": 50
            }
        }
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import Expectation

client = MockServerClient("localhost", 1080)
client.upsert(Expectation.from_dict({
    "httpRequest": {
        "path": "/some/path"
    },
    "httpResponse": {
        "body": "some_response_body",
        "delay": {
            "timeUnit": "MILLISECONDS",
            "distribution": {
                "type": "UNIFORM",
                "min": 100,
                "max": 500
            }
        }
    }
}))
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.upsert(MockServer::Expectation.from_hash({
    "httpRequest": {
        "path": "/some/path"
    },
    "httpResponse": {
        "body": "some_response_body",
        "delay": {
            "timeUnit": "MILLISECONDS",
            "distribution": {
                "type": "UNIFORM",
                "min": 100,
                "max": 500
            }
        }
    }
}))
package main

import (
    "bytes"
    "net/http"
)

func main() {
    body := []byte(`{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpResponse": {
        "body": "some_response_body",
        "delay": {
            "timeUnit": "MILLISECONDS",
            "distribution": {
                "type": "UNIFORM",
                "min": 100,
                "max": 500
            }
        }
    }
}`)
    req, _ := http.NewRequest("PUT",
        "http://localhost:1080/mockserver/expectation",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    http.DefaultClient.Do(req)
}
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
    ""httpRequest"": {
        ""path"": ""/some/path""
    },
    ""httpResponse"": {
        ""body"": ""some_response_body"",
        ""delay"": {
            ""timeUnit"": ""MILLISECONDS"",
            ""distribution"": {
                ""type"": ""UNIFORM"",
                ""min"": 100,
                ""max"": 500
            }
        }
    }
}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpResponse": {
        "body": "some_response_body",
        "delay": {
            "timeUnit": "MILLISECONDS",
            "distribution": {
                "type": "UNIFORM",
                "min": 100,
                "max": 500
            }
        }
    }
}"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
$json1 = <<<'JSON'
{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpResponse": {
        "body": "some_response_body",
        "delay": {
            "timeUnit": "MILLISECONDS",
            "distribution": {
                "type": "UNIFORM",
                "min": 100,
                "max": 500
            }
        }
    }
}
JSON;

$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_POSTFIELDS     => $json1,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json; charset=utf-8'],
    CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
curl_close($ch);

$json2 = <<<'JSON'
{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpResponse": {
        "body": "some_response_body",
        "delay": {
            "timeUnit": "MILLISECONDS",
            "distribution": {
                "type": "LOG_NORMAL",
                "median": 200,
                "p99": 800
            }
        }
    }
}
JSON;

$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_POSTFIELDS     => $json2,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json; charset=utf-8'],
    CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
curl_close($ch);

$json3 = <<<'JSON'
{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpResponse": {
        "body": "some_response_body",
        "delay": {
            "timeUnit": "MILLISECONDS",
            "distribution": {
                "type": "GAUSSIAN",
                "mean": 200,
                "stdDev": 50
            }
        }
    }
}
JSON;

$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_POSTFIELDS     => $json3,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json; charset=utf-8'],
    CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
curl_close($ch);
# uniform random delay between 100ms and 500ms
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpResponse": {
        "body": "some_response_body",
        "delay": {
            "timeUnit": "MILLISECONDS",
            "distribution": {
                "type": "UNIFORM",
                "min": 100,
                "max": 500
            }
        }
    }
}'

# log-normal delay with median 200ms and p99 of 800ms
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpResponse": {
        "body": "some_response_body",
        "delay": {
            "timeUnit": "MILLISECONDS",
            "distribution": {
                "type": "LOG_NORMAL",
                "median": 200,
                "p99": 800
            }
        }
    }
}'

# gaussian delay with mean 200ms and standard deviation of 50ms
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpResponse": {
        "body": "some_response_body",
        "delay": {
            "timeUnit": "MILLISECONDS",
            "distribution": {
                "type": "GAUSSIAN",
                "mean": 200,
                "stdDev": 50
            }
        }
    }
}'

See REST API for full JSON specification

A template-based delay computes the delay duration in milliseconds by rendering a Velocity or Mustache template against the incoming request, so the response time can depend on the request itself — for example, larger request payloads can respond more slowly. The template has the same request context (request.body, request.headers, etc.) available to response-body templates, and its rendered output is parsed as a whole number of milliseconds.

If the template renders a blank or non-numeric value (or fails for any reason) the delay falls back to the static value/timeUnit on the same delay object (which defaults to zero), so a misconfigured template never fails the response. Only VELOCITY and MUSTACHE are supported for delay templates.

// delay 10ms per character of the request body
new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/some/path")
    )
    .respond(
        response()
            .withBody("some_response_body")
            .withDelay(Delay.template(HttpTemplate.TemplateType.VELOCITY, "#set($d = $request.body.length() * 10)$d"))
    );
# delay 10ms per character of the request body
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpResponse": {
        "body": "some_response_body",
        "delay": {
            "templateType": "VELOCITY",
            "template": "#set($d = $request.body.length() * 10)$d"
        }
    }
}'

See REST API for full JSON specification

MockServerClient mockServerClient = new MockServerClient("localhost", 1080);

// respond once with 200, then respond twice with 204, then
// respond with 404 as no remaining active expectations
mockServerClient
    .when(
        request()
            .withPath("/some/path"),
        Times.exactly(1)
    )
    .respond(
        response()
            .withStatusCode(200)
    );

mockServerClient
    .when(
        request()
            .withPath("/some/path"),
        Times.exactly(2)
    )
    .respond(
        response()
            .withStatusCode(204)
    );
var client = require('mockserver-client').mockServerClient("localhost", 1080);

// respond once with 200, then respond twice with 204, then
// respond with 404 as no remaining active expectations
client.mockAnyResponse({
    "httpRequest": {
        "path": "/some/path"
    },
    "httpResponse": {
        "statusCode": 200
    },
    "times": {
        "remainingTimes": 1,
        "unlimited": false
    }
}).then(
    function () {
        console.log("first expectation created");

        client.mockAnyResponse({
            "httpRequest": {
                "path": "/some/path"
            },
            "httpResponse": {
                "statusCode": 204
            },
            "times": {
                "remainingTimes": 2,
                "unlimited": false
            }
        }).then(
            function () {
                console.log("second expectation created");
            },
            function (error) {
                console.log(error);
            }
        );
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import HttpRequest, HttpResponse, Times

client = MockServerClient("localhost", 1080)

# respond once with 200, then respond twice with 204, then
# respond with 404 as no remaining active expectations
client.when(
    HttpRequest.request(path="/some/path"),
    times=Times.exactly(1)
).respond(
    HttpResponse.response(status_code=200)
)

client.when(
    HttpRequest.request(path="/some/path"),
    times=Times.exactly(2)
).respond(
    HttpResponse.response(status_code=204)
)
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)

# respond once with 200, then respond twice with 204, then
# respond with 404 as no remaining active expectations
client.when(
    MockServer::HttpRequest.new(path: '/some/path'),
    times: MockServer::Times.exactly(1)
).respond(
    MockServer::HttpResponse.new(status_code: 200)
)

client.when(
    MockServer::HttpRequest.new(path: '/some/path'),
    times: MockServer::Times.exactly(2)
).respond(
    MockServer::HttpResponse.new(status_code: 204)
)
import mockserver "github.com/mock-server/mockserver-monorepo/mockserver-client-go"

client := mockserver.New("localhost", 1080)

// respond once with 200, then respond twice with 204, then
// respond with 404 as no remaining active expectations
client.When(
    mockserver.Request().Path("/some/path"),
    mockserver.WithTimes(mockserver.Exactly(1)),
).Respond(
    mockserver.Response().StatusCode(200),
)

client.When(
    mockserver.Request().Path("/some/path"),
    mockserver.WithTimes(mockserver.Exactly(2)),
).Respond(
    mockserver.Response().StatusCode(204),
)
using MockServer.Client;
using MockServer.Client.Models;

using var client = new MockServerClient("localhost", 1080);

// respond once with 200, then respond twice with 204, then
// respond with 404 as no remaining active expectations
client.When(
    HttpRequest.Request().WithPath("/some/path"),
    times: Times.Exactly(1)
).Respond(
    HttpResponse.Response().WithStatusCode(200)
);

client.When(
    HttpRequest.Request().WithPath("/some/path"),
    times: Times.Exactly(2)
).Respond(
    HttpResponse.Response().WithStatusCode(204)
);
use mockserver_client::{ClientBuilder, HttpRequest, HttpResponse, Times};

let client = ClientBuilder::new("localhost", 1080).build().unwrap();

// respond once with 200, then respond twice with 204, then
// respond with 404 as no remaining active expectations
client.when(HttpRequest::new().path("/some/path"))
    .times(Times::once())
    .respond(HttpResponse::new().status_code(200))
    .unwrap();

client.when(HttpRequest::new().path("/some/path"))
    .times(Times::exactly(2))
    .respond(HttpResponse::new().status_code(204))
    .unwrap();
use MockServer\MockServerClient;
use MockServer\HttpRequest;
use MockServer\HttpResponse;
use MockServer\Times;

$client = new MockServerClient('localhost', 1080);

// respond once with 200, then respond twice with 204, then
// respond with 404 as no remaining active expectations
$client->when(
    HttpRequest::request()
        ->path('/some/path'), Times::exactly(1)
)->respond(
    HttpResponse::response()
        ->statusCode(200)
);

$client->when(
    HttpRequest::request()
        ->path('/some/path'), Times::exactly(2)
)->respond(
    HttpResponse::response()
        ->statusCode(204)
);
# respond once with 200, then respond twice with 204, then
# respond with 404 as no remaining active expectations

curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpResponse": {
        "statusCode": 200
    },
    "times": {
        "remainingTimes": 1,
        "unlimited": false
    }
}'

curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpResponse": {
        "statusCode": 204
    },
    "times": {
        "remainingTimes": 2,
        "unlimited": false
    }
}'

See REST API for full JSON specification

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/some/path")
    )
    .respond(
        response()
            .withBody("some_response_body")
            .withConnectionOptions(
                connectionOptions()
                    .withSuppressConnectionHeader(true)
                    .withSuppressContentLengthHeader(true)
            )
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest" : {
        "path" : "/some/path"
    },
    "httpResponse" : {
        "body" : "some_response_body",
        "connectionOptions" : {
            "suppressContentLengthHeader" : true,
            "suppressConnectionHeader" : true
        }
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import Expectation

client = MockServerClient("localhost", 1080)
client.upsert(Expectation.from_dict({
    "httpRequest" : {
        "path" : "/some/path"
    },
    "httpResponse" : {
        "body" : "some_response_body",
        "connectionOptions" : {
            "suppressContentLengthHeader" : true,
            "suppressConnectionHeader" : true
        }
    }
}))
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.upsert(MockServer::Expectation.from_hash({
    "httpRequest" : {
        "path" : "/some/path"
    },
    "httpResponse" : {
        "body" : "some_response_body",
        "connectionOptions" : {
            "suppressContentLengthHeader" : true,
            "suppressConnectionHeader" : true
        }
    }
}))
package main

import (
    "bytes"
    "net/http"
)

func main() {
    body := []byte(`{
    "httpRequest" : {
        "path" : "/some/path"
    },
    "httpResponse" : {
        "body" : "some_response_body",
        "connectionOptions" : {
            "suppressContentLengthHeader" : true,
            "suppressConnectionHeader" : true
        }
    }
}`)
    req, _ := http.NewRequest("PUT",
        "http://localhost:1080/mockserver/expectation",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    http.DefaultClient.Do(req)
}
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
    ""httpRequest"" : {
        ""path"" : ""/some/path""
    },
    ""httpResponse"" : {
        ""body"" : ""some_response_body"",
        ""connectionOptions"" : {
            ""suppressContentLengthHeader"" : true,
            ""suppressConnectionHeader"" : true
        }
    }
}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
    "httpRequest" : {
        "path" : "/some/path"
    },
    "httpResponse" : {
        "body" : "some_response_body",
        "connectionOptions" : {
            "suppressContentLengthHeader" : true,
            "suppressConnectionHeader" : true
        }
    }
}"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
$json = <<<'JSON'
{
    "httpRequest" : {
        "path" : "/some/path"
    },
    "httpResponse" : {
        "body" : "some_response_body",
        "connectionOptions" : {
            "suppressContentLengthHeader" : true,
            "suppressConnectionHeader" : true
        }
    }
}
JSON;

$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_POSTFIELDS     => $json,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json; charset=utf-8'],
    CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
curl_close($ch);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest" : {
        "path" : "/some/path"
    },
    "httpResponse" : {
        "body" : "some_response_body",
        "connectionOptions" : {
            "suppressContentLengthHeader" : true,
            "suppressConnectionHeader" : true
        }
    }
}'

See REST API for full JSON specification

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/some/path")
    )
    .respond(
        response()
            .withBody("some_response_body")
            .withConnectionOptions(
                connectionOptions()
                    .withKeepAliveOverride(false)
                    .withContentLengthHeaderOverride(10)
            )
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest" : {
        "path" : "/some/path"
    },
    "httpResponse" : {
        "body" : "some_response_body",
        "connectionOptions" : {
            "contentLengthHeaderOverride" : 10,
            "keepAliveOverride" : false
        }
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import Expectation

client = MockServerClient("localhost", 1080)
client.upsert(Expectation.from_dict({
    "httpRequest" : {
        "path" : "/some/path"
    },
    "httpResponse" : {
        "body" : "some_response_body",
        "connectionOptions" : {
            "contentLengthHeaderOverride" : 10,
            "keepAliveOverride" : false
        }
    }
}))
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.upsert(MockServer::Expectation.from_hash({
    "httpRequest" : {
        "path" : "/some/path"
    },
    "httpResponse" : {
        "body" : "some_response_body",
        "connectionOptions" : {
            "contentLengthHeaderOverride" : 10,
            "keepAliveOverride" : false
        }
    }
}))
package main

import (
    "bytes"
    "net/http"
)

func main() {
    body := []byte(`{
    "httpRequest" : {
        "path" : "/some/path"
    },
    "httpResponse" : {
        "body" : "some_response_body",
        "connectionOptions" : {
            "contentLengthHeaderOverride" : 10,
            "keepAliveOverride" : false
        }
    }
}`)
    req, _ := http.NewRequest("PUT",
        "http://localhost:1080/mockserver/expectation",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    http.DefaultClient.Do(req)
}
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
    ""httpRequest"" : {
        ""path"" : ""/some/path""
    },
    ""httpResponse"" : {
        ""body"" : ""some_response_body"",
        ""connectionOptions"" : {
            ""contentLengthHeaderOverride"" : 10,
            ""keepAliveOverride"" : false
        }
    }
}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
    "httpRequest" : {
        "path" : "/some/path"
    },
    "httpResponse" : {
        "body" : "some_response_body",
        "connectionOptions" : {
            "contentLengthHeaderOverride" : 10,
            "keepAliveOverride" : false
        }
    }
}"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
$json = <<<'JSON'
{
    "httpRequest" : {
        "path" : "/some/path"
    },
    "httpResponse" : {
        "body" : "some_response_body",
        "connectionOptions" : {
            "contentLengthHeaderOverride" : 10,
            "keepAliveOverride" : false
        }
    }
}
JSON;

$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_POSTFIELDS     => $json,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json; charset=utf-8'],
    CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
curl_close($ch);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest" : {
        "path" : "/some/path"
    },
    "httpResponse" : {
        "body" : "some_response_body",
        "connectionOptions" : {
            "contentLengthHeaderOverride" : 10,
            "keepAliveOverride" : false
        }
    }
}'

See REST API for full JSON specification

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/some/path")
    )
    .respond(
        response()
            .withBody("some_response_body")
            .withConnectionOptions(
                connectionOptions()
                    .withCloseSocket(true)
            )
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest" : {
        "path" : "/some/path"
    },
    "httpResponse" : {
        "body" : "some_response_body",
        "connectionOptions" : {
            "closeSocket" : true
        }
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import Expectation

client = MockServerClient("localhost", 1080)
client.upsert(Expectation.from_dict({
    "httpRequest" : {
        "path" : "/some/path"
    },
    "httpResponse" : {
        "body" : "some_response_body",
        "connectionOptions" : {
            "closeSocket" : true
        }
    }
}))
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.upsert(MockServer::Expectation.from_hash({
    "httpRequest" : {
        "path" : "/some/path"
    },
    "httpResponse" : {
        "body" : "some_response_body",
        "connectionOptions" : {
            "closeSocket" : true
        }
    }
}))
package main

import (
    "bytes"
    "net/http"
)

func main() {
    body := []byte(`{
    "httpRequest" : {
        "path" : "/some/path"
    },
    "httpResponse" : {
        "body" : "some_response_body",
        "connectionOptions" : {
            "closeSocket" : true
        }
    }
}`)
    req, _ := http.NewRequest("PUT",
        "http://localhost:1080/mockserver/expectation",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    http.DefaultClient.Do(req)
}
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
    ""httpRequest"" : {
        ""path"" : ""/some/path""
    },
    ""httpResponse"" : {
        ""body"" : ""some_response_body"",
        ""connectionOptions"" : {
            ""closeSocket"" : true
        }
    }
}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
    "httpRequest" : {
        "path" : "/some/path"
    },
    "httpResponse" : {
        "body" : "some_response_body",
        "connectionOptions" : {
            "closeSocket" : true
        }
    }
}"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
$json = <<<'JSON'
{
    "httpRequest" : {
        "path" : "/some/path"
    },
    "httpResponse" : {
        "body" : "some_response_body",
        "connectionOptions" : {
            "closeSocket" : true
        }
    }
}
JSON;

$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_POSTFIELDS     => $json,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json; charset=utf-8'],
    CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
curl_close($ch);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest" : {
        "path" : "/some/path"
    },
    "httpResponse" : {
        "body" : "some_response_body",
        "connectionOptions" : {
            "closeSocket" : true
        }
    }
}'

See REST API for full JSON specification

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/some/path")
    )
    .respond(
        response()
            .withBody("some_response_body")
            .withConnectionOptions(
                connectionOptions()
                    .withCloseSocket(true)
                    .withCloseSocketDelay(new Delay(MILLISECONDS, 500))
            )
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest" : {
        "path" : "/some/path"
    },
    "httpResponse" : {
        "body" : "some_response_body",
        "connectionOptions" : {
            "closeSocket" : true,
            "closeSocketDelay" : {
                "timeUnit" : "MILLISECONDS",
                "value" : 500
            }
        }
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import Expectation

client = MockServerClient("localhost", 1080)
client.upsert(Expectation.from_dict({
    "httpRequest" : {
        "path" : "/some/path"
    },
    "httpResponse" : {
        "body" : "some_response_body",
        "connectionOptions" : {
            "closeSocket" : true,
            "closeSocketDelay" : {
                "timeUnit" : "MILLISECONDS",
                "value" : 500
            }
        }
    }
}))
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.upsert(MockServer::Expectation.from_hash({
    "httpRequest" : {
        "path" : "/some/path"
    },
    "httpResponse" : {
        "body" : "some_response_body",
        "connectionOptions" : {
            "closeSocket" : true,
            "closeSocketDelay" : {
                "timeUnit" : "MILLISECONDS",
                "value" : 500
            }
        }
    }
}))
package main

import (
    "bytes"
    "net/http"
)

func main() {
    body := []byte(`{
    "httpRequest" : {
        "path" : "/some/path"
    },
    "httpResponse" : {
        "body" : "some_response_body",
        "connectionOptions" : {
            "closeSocket" : true,
            "closeSocketDelay" : {
                "timeUnit" : "MILLISECONDS",
                "value" : 500
            }
        }
    }
}`)
    req, _ := http.NewRequest("PUT",
        "http://localhost:1080/mockserver/expectation",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    http.DefaultClient.Do(req)
}
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
    ""httpRequest"" : {
        ""path"" : ""/some/path""
    },
    ""httpResponse"" : {
        ""body"" : ""some_response_body"",
        ""connectionOptions"" : {
            ""closeSocket"" : true,
            ""closeSocketDelay"" : {
                ""timeUnit"" : ""MILLISECONDS"",
                ""value"" : 500
            }
        }
    }
}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
    "httpRequest" : {
        "path" : "/some/path"
    },
    "httpResponse" : {
        "body" : "some_response_body",
        "connectionOptions" : {
            "closeSocket" : true,
            "closeSocketDelay" : {
                "timeUnit" : "MILLISECONDS",
                "value" : 500
            }
        }
    }
}"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
$json = <<<'JSON'
{
    "httpRequest" : {
        "path" : "/some/path"
    },
    "httpResponse" : {
        "body" : "some_response_body",
        "connectionOptions" : {
            "closeSocket" : true,
            "closeSocketDelay" : {
                "timeUnit" : "MILLISECONDS",
                "value" : 500
            }
        }
    }
}
JSON;

$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_POSTFIELDS     => $json,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json; charset=utf-8'],
    CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
curl_close($ch);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest" : {
        "path" : "/some/path"
    },
    "httpResponse" : {
        "body" : "some_response_body",
        "connectionOptions" : {
            "closeSocket" : true,
            "closeSocketDelay" : {
                "timeUnit" : "MILLISECONDS",
                "value" : 500
            }
        }
    }
}'

See REST API for full JSON specification

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/some/path")
    )
    .respond(
        response()
            .withBody("some_long_response_body_delivered_in_chunks")
            .withConnectionOptions(
                connectionOptions()
                    .withChunkSize(10)
                    .withChunkDelay(new Delay(MILLISECONDS, 500))
            )
    );
from mockserver.client import MockServerClient
from mockserver.models import Expectation

client = MockServerClient("localhost", 1080)
client.upsert(Expectation.from_dict({
    "httpRequest" : {
        "path" : "/some/path"
    },
    "httpResponse" : {
        "body" : "some_long_response_body_delivered_in_chunks",
        "connectionOptions" : {
            "chunkSize" : 10,
            "chunkDelay" : {
                "timeUnit" : "MILLISECONDS",
                "value" : 500
            }
        }
    }
}))
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.upsert(MockServer::Expectation.from_hash({
    "httpRequest" : {
        "path" : "/some/path"
    },
    "httpResponse" : {
        "body" : "some_long_response_body_delivered_in_chunks",
        "connectionOptions" : {
            "chunkSize" : 10,
            "chunkDelay" : {
                "timeUnit" : "MILLISECONDS",
                "value" : 500
            }
        }
    }
}))
package main

import (
    "bytes"
    "net/http"
)

func main() {
    body := []byte(`{
    "httpRequest" : {
        "path" : "/some/path"
    },
    "httpResponse" : {
        "body" : "some_long_response_body_delivered_in_chunks",
        "connectionOptions" : {
            "chunkSize" : 10,
            "chunkDelay" : {
                "timeUnit" : "MILLISECONDS",
                "value" : 500
            }
        }
    }
}`)
    req, _ := http.NewRequest("PUT",
        "http://localhost:1080/mockserver/expectation",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    http.DefaultClient.Do(req)
}
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
    ""httpRequest"" : {
        ""path"" : ""/some/path""
    },
    ""httpResponse"" : {
        ""body"" : ""some_long_response_body_delivered_in_chunks"",
        ""connectionOptions"" : {
            ""chunkSize"" : 10,
            ""chunkDelay"" : {
                ""timeUnit"" : ""MILLISECONDS"",
                ""value"" : 500
            }
        }
    }
}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
    "httpRequest" : {
        "path" : "/some/path"
    },
    "httpResponse" : {
        "body" : "some_long_response_body_delivered_in_chunks",
        "connectionOptions" : {
            "chunkSize" : 10,
            "chunkDelay" : {
                "timeUnit" : "MILLISECONDS",
                "value" : 500
            }
        }
    }
}"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
$json = <<<'JSON'
{
    "httpRequest" : {
        "path" : "/some/path"
    },
    "httpResponse" : {
        "body" : "some_long_response_body_delivered_in_chunks",
        "connectionOptions" : {
            "chunkSize" : 10,
            "chunkDelay" : {
                "timeUnit" : "MILLISECONDS",
                "value" : 500
            }
        }
    }
}
JSON;

$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_POSTFIELDS     => $json,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json; charset=utf-8'],
    CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
curl_close($ch);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest" : {
        "path" : "/some/path"
    },
    "httpResponse" : {
        "body" : "some_long_response_body_delivered_in_chunks",
        "connectionOptions" : {
            "chunkSize" : 10,
            "chunkDelay" : {
                "timeUnit" : "MILLISECONDS",
                "value" : 500
            }
        }
    }
}'

See REST API for full JSON specification

// $!request.headers['Session-Id'] returns an array of values because headers and queryStringParameters have multiple values
new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/some/path")
    )
    .respond(
        template(
            HttpTemplate.TemplateType.JAVASCRIPT,
            "return {\n" +
                "     'statusCode': 200,\n" +
                "     'cookies': {\n" +
                "          'session' : request.headers['Session-Id'][0]\n" +
                "     },\n" +
                "     'headers': {\n" +
                "          'Date' : Date()\n" +
                "     },\n" +
                "     'body': JSON.stringify(\n" +
                "               {\n" +
                "                    method: request.method,\n" +
                "                    path: request.path,\n" +
                "                    body: request.body\n" +
                "               }\n" +
                "          )\n" +
                "};"
        )
    );
var mockServerClient = require('mockserver-client').mockServerClient;
// $!request.headers['Session-Id'] returns an array of values because headers and queryStringParameters have multiple values
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "path": "/some/path"
    },
    "httpResponseTemplate": {
        "template": "return { statusCode: 200, cookies: { session: request.headers[\"Session-Id\"] && request.headers[\"Session-Id\"][0] }, headers: { Date: [ Date() ] }, body: JSON.stringify({method: request.method, path: request.path, body: request.body}) };",
        "templateType": "JAVASCRIPT"
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import Expectation

client = MockServerClient("localhost", 1080)
client.upsert(Expectation.from_dict({
    "httpRequest": {
        "path": "/some/path"
    },
    "httpResponseTemplate": {
        "template": "return { statusCode: 200, cookies: { session: request.headers[\"Session-Id\"] && request.headers[\"Session-Id\"][0] }, headers: { Date: [ Date() ] }, body: JSON.stringify({method: request.method, path: request.path, body: request.body}) };",
        "templateType": "JAVASCRIPT"
    }
}))
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.upsert(MockServer::Expectation.from_hash({
    "httpRequest": {
        "path": "/some/path"
    },
    "httpResponseTemplate": {
        "template": "return { statusCode: 200, cookies: { session: request.headers[\"Session-Id\"] && request.headers[\"Session-Id\"][0] }, headers: { Date: [ Date() ] }, body: JSON.stringify({method: request.method, path: request.path, body: request.body}) };",
        "templateType": "JAVASCRIPT"
    }
}))
package main

import (
    "bytes"
    "net/http"
)

func main() {
    body := []byte(`{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpResponseTemplate": {
        "template": "return { statusCode: 200, cookies: { session: request.headers[\"Session-Id\"] && request.headers[\"Session-Id\"][0] }, headers: { Date: [ Date() ] }, body: JSON.stringify({method: request.method, path: request.path, body: request.body}) };",
        "templateType": "JAVASCRIPT"
    }
}`)
    req, _ := http.NewRequest("PUT",
        "http://localhost:1080/mockserver/expectation",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    http.DefaultClient.Do(req)
}
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
    ""httpRequest"": {
        ""path"": ""/some/path""
    },
    ""httpResponseTemplate"": {
        ""template"": ""return { statusCode: 200, cookies: { session: request.headers[\""Session-Id\""] && request.headers[\""Session-Id\""][0] }, headers: { Date: [ Date() ] }, body: JSON.stringify({method: request.method, path: request.path, body: request.body}) };"",
        ""templateType"": ""JAVASCRIPT""
    }
}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpResponseTemplate": {
        "template": "return { statusCode: 200, cookies: { session: request.headers[\"Session-Id\"] && request.headers[\"Session-Id\"][0] }, headers: { Date: [ Date() ] }, body: JSON.stringify({method: request.method, path: request.path, body: request.body}) };",
        "templateType": "JAVASCRIPT"
    }
}"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
$json = <<<'JSON'
{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpResponseTemplate": {
        "template": "return { statusCode: 200, cookies: { session: request.headers[\"Session-Id\"] && request.headers[\"Session-Id\"][0] }, headers: { Date: [ Date() ] }, body: JSON.stringify({method: request.method, path: request.path, body: request.body}) };",
        "templateType": "JAVASCRIPT"
    }
}
JSON;

$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_POSTFIELDS     => $json,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json; charset=utf-8'],
    CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
curl_close($ch);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpResponseTemplate": {
        "template": "return { statusCode: 200, cookies: { session: request.headers[\"Session-Id\"] && request.headers[\"Session-Id\"][0] }, headers: { Date: [ Date() ] }, body: JSON.stringify({method: request.method, path: request.path, body: request.body}) };",
        "templateType": "JAVASCRIPT"
    }
}'

See REST API for full JSON specification

To simplify handling different types of bodies, JavaScript and Velocity templates, have access to both an object request.body field and a string request.bodyAsString field which can be used as shown in the examples below.

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/some/path")
    )
    .respond(
        template(
            HttpTemplate.TemplateType.JAVASCRIPT,
            "return { statusCode: 200, headers: { Date: [ Date() ] }, body: JSON.stringify({is_active: JSON.parse(request.bodyAsString).is_active, id: \"1234\", name: \"taras\"}) };"
        )
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "path": "/some/path"
    },
    "httpResponseTemplate": {
        "template": "return { statusCode: 200, headers: { Date: [ Date() ] }, body: JSON.stringify({is_active: JSON.parse(request.bodyAsString).is_active, id: \"1234\", name: \"taras\"}) };",
        "templateType": "JAVASCRIPT"
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import Expectation

client = MockServerClient("localhost", 1080)
client.upsert(Expectation.from_dict({
    "httpRequest": {
        "path": "/some/path"
    },
    "httpResponseTemplate": {
        "template": "return { statusCode: 200, headers: { Date: [ Date() ] }, body: JSON.stringify({is_active: JSON.parse(request.bodyAsString).is_active, id: \"1234\", name: \"taras\"}) };",
        "templateType": "JAVASCRIPT"
    }
}))
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.upsert(MockServer::Expectation.from_hash({
    "httpRequest": {
        "path": "/some/path"
    },
    "httpResponseTemplate": {
        "template": "return { statusCode: 200, headers: { Date: [ Date() ] }, body: JSON.stringify({is_active: JSON.parse(request.bodyAsString).is_active, id: \"1234\", name: \"taras\"}) };",
        "templateType": "JAVASCRIPT"
    }
}))
package main

import (
    "bytes"
    "net/http"
)

func main() {
    body := []byte(`{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpResponseTemplate": {
        "template": "return { statusCode: 200, headers: { Date: [ Date() ] }, body: JSON.stringify({is_active: JSON.parse(request.bodyAsString).is_active, id: \"1234\", name: \"taras\"}) };",
        "templateType": "JAVASCRIPT"
    }
}`)
    req, _ := http.NewRequest("PUT",
        "http://localhost:1080/mockserver/expectation",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    http.DefaultClient.Do(req)
}
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
    ""httpRequest"": {
        ""path"": ""/some/path""
    },
    ""httpResponseTemplate"": {
        ""template"": ""return { statusCode: 200, headers: { Date: [ Date() ] }, body: JSON.stringify({is_active: JSON.parse(request.bodyAsString).is_active, id: \""1234\"", name: \""taras\""}) };"",
        ""templateType"": ""JAVASCRIPT""
    }
}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpResponseTemplate": {
        "template": "return { statusCode: 200, headers: { Date: [ Date() ] }, body: JSON.stringify({is_active: JSON.parse(request.bodyAsString).is_active, id: \"1234\", name: \"taras\"}) };",
        "templateType": "JAVASCRIPT"
    }
}"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
$json = <<<'JSON'
{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpResponseTemplate": {
        "template": "return { statusCode: 200, headers: { Date: [ Date() ] }, body: JSON.stringify({is_active: JSON.parse(request.bodyAsString).is_active, id: \"1234\", name: \"taras\"}) };",
        "templateType": "JAVASCRIPT"
    }
}
JSON;

$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_POSTFIELDS     => $json,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json; charset=utf-8'],
    CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
curl_close($ch);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpResponseTemplate": {
        "template": "return { statusCode: 200, headers: { Date: [ Date() ] }, body: JSON.stringify({is_active: JSON.parse(request.bodyAsString).is_active, id: \"1234\", name: \"taras\"}) };",
        "templateType": "JAVASCRIPT"
    }
}'

See REST API for full JSON specification

String template = "" +
    "if (request.method === 'POST' && request.path === '/somePath') {\n" +
    "    return {\n" +
    "        'statusCode': 200,\n" +
    "        'body': JSON.stringify({name: 'value'})\n" +
    "    };\n" +
    "} else {\n" +
    "    return {\n" +
    "        'statusCode': 406,\n" +
    "        'body': request.body\n" +
    "    };\n" +
    "}";

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/some/path")
    )
    .respond(
        template(HttpTemplate.TemplateType.JAVASCRIPT)
            .withTemplate(template)
            .withDelay(TimeUnit.MINUTES, 2)
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {"path": "/some/path"},
    "httpResponseTemplate": {
        "template": "if (request.method === \"POST\" && request.path === \"/some/path\") { return { statusCode: 200, body: JSON.stringify({name: \"value\"}) }; } else { return { statusCode: 406, body: request.body }; }",
        "templateType": "JAVASCRIPT",
        "delay": {"timeUnit": "MINUTES", "value": 2}
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import Expectation

client = MockServerClient("localhost", 1080)
client.upsert(Expectation.from_dict({
    "httpRequest": {"path": "/some/path"},
    "httpResponseTemplate": {
        "template": "if (request.method === \"POST\" && request.path === \"/some/path\") { return { statusCode: 200, body: JSON.stringify({name: \"value\"}) }; } else { return { statusCode: 406, body: request.body }; }",
        "templateType": "JAVASCRIPT",
        "delay": {"timeUnit": "MINUTES", "value": 2}
    }
}))
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.upsert(MockServer::Expectation.from_hash({
    "httpRequest": {"path": "/some/path"},
    "httpResponseTemplate": {
        "template": "if (request.method === \"POST\" && request.path === \"/some/path\") { return { statusCode: 200, body: JSON.stringify({name: \"value\"}) }; } else { return { statusCode: 406, body: request.body }; }",
        "templateType": "JAVASCRIPT",
        "delay": {"timeUnit": "MINUTES", "value": 2}
    }
}))
package main

import (
    "bytes"
    "net/http"
)

func main() {
    body := []byte(`{
    "httpRequest": {"path": "/some/path"},
    "httpResponseTemplate": {
        "template": "if (request.method === \"POST\" && request.path === \"/some/path\") { return { statusCode: 200, body: JSON.stringify({name: \"value\"}) }; } else { return { statusCode: 406, body: request.body }; }",
        "templateType": "JAVASCRIPT",
        "delay": {"timeUnit": "MINUTES", "value": 2}
    }
}`)
    req, _ := http.NewRequest("PUT",
        "http://localhost:1080/mockserver/expectation",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    http.DefaultClient.Do(req)
}
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
    ""httpRequest"": {""path"": ""/some/path""},
    ""httpResponseTemplate"": {
        ""template"": ""if (request.method === \""POST\"" && request.path === \""/some/path\"") { return { statusCode: 200, body: JSON.stringify({name: \""value\""}) }; } else { return { statusCode: 406, body: request.body }; }"",
        ""templateType"": ""JAVASCRIPT"",
        ""delay"": {""timeUnit"": ""MINUTES"", ""value"": 2}
    }
}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
    "httpRequest": {"path": "/some/path"},
    "httpResponseTemplate": {
        "template": "if (request.method === \"POST\" && request.path === \"/some/path\") { return { statusCode: 200, body: JSON.stringify({name: \"value\"}) }; } else { return { statusCode: 406, body: request.body }; }",
        "templateType": "JAVASCRIPT",
        "delay": {"timeUnit": "MINUTES", "value": 2}
    }
}"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
$json = <<<'JSON'
{
    "httpRequest": {"path": "/some/path"},
    "httpResponseTemplate": {
        "template": "if (request.method === \"POST\" && request.path === \"/some/path\") { return { statusCode: 200, body: JSON.stringify({name: \"value\"}) }; } else { return { statusCode: 406, body: request.body }; }",
        "templateType": "JAVASCRIPT",
        "delay": {"timeUnit": "MINUTES", "value": 2}
    }
}
JSON;

$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_POSTFIELDS     => $json,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json; charset=utf-8'],
    CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
curl_close($ch);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest": {"path": "/some/path"},
    "httpResponseTemplate": {
        "template": "if (request.method === \"POST\" && request.path === \"/some/path\") { return { statusCode: 200, body: JSON.stringify({name: \"value\"}) }; } else { return { statusCode: 406, body: request.body }; }",
        "templateType": "JAVASCRIPT",
        "delay": {"timeUnit": "MINUTES", "value": 2}
    }
}'

See REST API for full JSON specification

// $!request.headers['Session-Id'] and $!request.headers['User-Agent'] both returns an
// array of values because headers and queryStringParameters have multiple values
new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/some/path")
    )
    .respond(
        template(
            HttpTemplate.TemplateType.VELOCITY,
            "{\n" +
                "     \"statusCode\": 200,\n" +
                "     \"cookies\": { \n" +
                "          \"session\": \"$!request.headers['Session-Id'][0]\"\n" +
                "     },\n" +
                "     \"headers\": {\n" +
                "          \"Client-User-Agent\": [ \"$!request.headers['User-Agent'][0]\" ]\n" +
                "     },\n" +
                "     \"body\": $!request.body\n" +
                "}"
        )
    );
var mockServerClient = require('mockserver-client').mockServerClient;
// $!request.headers['Session-Id'] and $!request.headers['User-Agent'] both returns an
// array of values because headers and queryStringParameters have multiple values
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "path": "/some/path"
    },
    "httpResponseTemplate": {
        "template": "{ \"statusCode\": 200, \"cookies\": { \"session\": \"$!request.headers[\"Session-Id\"][0]\" }, \"headers\": { \"Client-User-Agent\": [ \"$!request.headers[\"User-Agent\"][0]\" ] }, \"body\": \"$!request.body\" }",
        "templateType": "VELOCITY"
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import Expectation

client = MockServerClient("localhost", 1080)
client.upsert(Expectation.from_dict({
    "httpRequest": {
        "path": "/some/path"
    },
    "httpResponseTemplate": {
        "template": "{ \"statusCode\": 200, \"cookies\": { \"session\": \"$!request.headers[\"Session-Id\"][0]\" }, \"headers\": { \"Client-User-Agent\": [ \"$!request.headers[\"User-Agent\"][0]\" ] }, \"body\": \"$!request.body\" }",
        "templateType": "VELOCITY"
    }
}))
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.upsert(MockServer::Expectation.from_hash({
    "httpRequest": {
        "path": "/some/path"
    },
    "httpResponseTemplate": {
        "template": "{ \"statusCode\": 200, \"cookies\": { \"session\": \"$!request.headers[\"Session-Id\"][0]\" }, \"headers\": { \"Client-User-Agent\": [ \"$!request.headers[\"User-Agent\"][0]\" ] }, \"body\": \"$!request.body\" }",
        "templateType": "VELOCITY"
    }
}))
package main

import (
    "bytes"
    "net/http"
)

func main() {
    body := []byte(`{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpResponseTemplate": {
        "template": "{ \"statusCode\": 200, \"cookies\": { \"session\": \"$!request.headers[\"Session-Id\"][0]\" }, \"headers\": { \"Client-User-Agent\": [ \"$!request.headers[\"User-Agent\"][0]\" ] }, \"body\": \"$!request.body\" }",
        "templateType": "VELOCITY"
    }
}`)
    req, _ := http.NewRequest("PUT",
        "http://localhost:1080/mockserver/expectation",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    http.DefaultClient.Do(req)
}
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
    ""httpRequest"": {
        ""path"": ""/some/path""
    },
    ""httpResponseTemplate"": {
        ""template"": ""{ \""statusCode\"": 200, \""cookies\"": { \""session\"": \""$!request.headers[\""Session-Id\""][0]\"" }, \""headers\"": { \""Client-User-Agent\"": [ \""$!request.headers[\""User-Agent\""][0]\"" ] }, \""body\"": \""$!request.body\"" }"",
        ""templateType"": ""VELOCITY""
    }
}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpResponseTemplate": {
        "template": "{ \"statusCode\": 200, \"cookies\": { \"session\": \"$!request.headers[\"Session-Id\"][0]\" }, \"headers\": { \"Client-User-Agent\": [ \"$!request.headers[\"User-Agent\"][0]\" ] }, \"body\": \"$!request.body\" }",
        "templateType": "VELOCITY"
    }
}"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
$json = <<<'JSON'
{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpResponseTemplate": {
        "template": "{ \"statusCode\": 200, \"cookies\": { \"session\": \"$!request.headers[\"Session-Id\"][0]\" }, \"headers\": { \"Client-User-Agent\": [ \"$!request.headers[\"User-Agent\"][0]\" ] }, \"body\": \"$!request.body\" }",
        "templateType": "VELOCITY"
    }
}
JSON;

$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_POSTFIELDS     => $json,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json; charset=utf-8'],
    CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
curl_close($ch);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpResponseTemplate": {
        "template": "{ \"statusCode\": 200, \"cookies\": { \"session\": \"$!request.headers[\"Session-Id\"][0]\" }, \"headers\": { \"Client-User-Agent\": [ \"$!request.headers[\"User-Agent\"][0]\" ] }, \"body\": \"$!request.body\" }",
        "templateType": "VELOCITY"
    }
}'

See REST API for full JSON specification

public class CallbackActionExamples {

    public void responseClassCallback() {
        new ClientAndServer(1080)
            .when(
                request()
                    .withPath("/some.*")
            )
            .respond(
                callback()
                    .withCallbackClass(TestExpectationResponseCallback.class)
            );
    }

    public static class TestExpectationResponseCallback implements ExpectationResponseCallback {

        @Override
        public HttpResponse handle(HttpRequest httpRequest) {
            if (httpRequest.getPath().getValue().endsWith("/path")) {
                return response()
                    .withStatusCode(HttpStatusCode.ACCEPTED_202.code())
                    .withHeaders(
                        header("x-callback", "test_callback_header"),
                        header("Content-Length", "a_callback_response".getBytes(UTF_8).length),
                        header("Connection", "keep-alive")
                    )
                    .withBody("a_callback_response");
            } else {
                return notFoundResponse();
            }
        }
    }

}
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "path": "/some.*"
    },
    "httpResponseClassCallback": {
        "callbackClass": "org.mockserver.examples.mockserver.CallbackActionExamples$TestExpectationResponseCallback"
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);
from mockserver.client import MockServerClient
from mockserver.models import Expectation

client = MockServerClient("localhost", 1080)
client.upsert(Expectation.from_dict({
    "httpRequest" : {
        "path" : "/some.*"
    },
    "httpResponseClassCallback" : {
        "callbackClass" : "org.mockserver.examples.mockserver.CallbackActionExamples$TestExpectationResponseCallback"
    }
}))
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.upsert(MockServer::Expectation.from_hash({
    "httpRequest" : {
        "path" : "/some.*"
    },
    "httpResponseClassCallback" : {
        "callbackClass" : "org.mockserver.examples.mockserver.CallbackActionExamples$TestExpectationResponseCallback"
    }
}))
package main

import (
    "bytes"
    "net/http"
)

func main() {
    body := []byte(`{
    "httpRequest" : {
        "path" : "/some.*"
    },
    "httpResponseClassCallback" : {
        "callbackClass" : "org.mockserver.examples.mockserver.CallbackActionExamples$TestExpectationResponseCallback"
    }
}`)
    req, _ := http.NewRequest("PUT",
        "http://localhost:1080/mockserver/expectation",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    http.DefaultClient.Do(req)
}
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
    ""httpRequest"" : {
        ""path"" : ""/some.*""
    },
    ""httpResponseClassCallback"" : {
        ""callbackClass"" : ""org.mockserver.examples.mockserver.CallbackActionExamples$TestExpectationResponseCallback""
    }
}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
    "httpRequest" : {
        "path" : "/some.*"
    },
    "httpResponseClassCallback" : {
        "callbackClass" : "org.mockserver.examples.mockserver.CallbackActionExamples$TestExpectationResponseCallback"
    }
}"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
$json = <<<'JSON'
{
    "httpRequest" : {
        "path" : "/some.*"
    },
    "httpResponseClassCallback" : {
        "callbackClass" : "org.mockserver.examples.mockserver.CallbackActionExamples$TestExpectationResponseCallback"
    }
}
JSON;

$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_POSTFIELDS     => $json,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json; charset=utf-8'],
    CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
curl_close($ch);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest" : {
        "path" : "/some.*"
    },
    "httpResponseClassCallback" : {
        "callbackClass" : "org.mockserver.examples.mockserver.CallbackActionExamples$TestExpectationResponseCallback"
    }
}'

To use a class callback MockServer must be able to load the class from the classpath.

The callback class must:

  • implement
    • org.mockserver.mock.action.ExpectationResponseCallback to dynamically override the response
  • have a zero argument constructor
  • be available in the classpath of the MockServer

If MockServer is started using the the JUnit 4 @Rule, the JUnit 5 Test Extension, ClientAndServer or directly using org.mockserver.netty.MockServer then any class present in the main or test classpaths will be visible to MockServer.

If MockServer is started using the maven plugin only the non-forked goals (such as runAndWait and start) will be able to load classes from the main and test classpaths. It is possible to use classes from a separate maven dependency, however, this dependency must be specified in the plugin configuration dependencies section. Any dependency added to the plugin configuration dependencies section will then be visible to MockServer run using both forked and non-forked goals.

The following configuration shows how to use classes from a separate maven dependency in callback actions.

 <plugin>
     <groupId>org.mock-server</groupId>
     <artifactId>mockserver-maven-plugin</artifactId>
     <version>7.2.0</version>
     <configuration>
        <serverPort>1080</serverPort>
        <logLevel>DEBUG</logLevel>
        <pipeLogToConsole>true</pipeLogToConsole>
     </configuration>
     <executions>
         <execution>
             <id>pre-integration-test</id>
             <phase>pre-integration-test</phase>
             <goals>
                 <goal>runForked</goal>
             </goals>
         </execution>
         <execution>
             <id>post-integration-test</id>
             <phase>post-integration-test</phase>
             <goals>
                 <goal>stopForked</goal>
             </goals>
         </execution>
     </executions>
     <dependencies>
         <dependency>
             <groupId>com.my-domain</groupId>
             <artifactId>my-callback-dependency</artifactId>
             <version>1.0.0</version>
         </dependency>
     </dependencies>
 </plugin>

If MockServer is started using the command line then the callback classes must be added to the JVM using the classpath command line switch (cp or classpath). The classpath switch is ignored by the JVM if the jar switch is used. So to run the MockServer from the command line directly (with mockserver-netty-7.2.0-no-dependencies.jar) you must specify the org.mockserver.cli.Main main class specifically and not use the jar switch as follows.

java -Dfile.encoding=UTF-8 -cp mockserver-netty-7.2.0-no-dependencies.jar:my-callback-dependency.jar org.mockserver.cli.Main -serverPort 1080
new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/some/path")
    )
    .respond(
        new ExpectationResponseCallback() {
            @Override
            public HttpResponse handle(HttpRequest httpRequest) {
                if (httpRequest.getMethod().getValue().equals("POST")) {
                    return response()
                        .withStatusCode(ACCEPTED_202.code())
                        .withHeaders(
                            header("x-object-callback", "test_object_callback_header")
                        )
                        .withBody("an_object_callback_response");
                } else {
                    return notFoundResponse();
                }
            }
        }
    );
new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/some/path")
    )
    .respond(
        request -> {
            if (request.getMethod().getValue().equals("POST")) {
                return response()
                    .withStatusCode(ACCEPTED_202.code())
                    .withHeaders(
                        header("x-object-callback", "test_object_callback_header")
                    )
                    .withBody("an_object_callback_response");
            } else {
                return notFoundResponse();
            }
        }
    );
var mockServerClient = require('mockserver-client').mockServerClient;
var callback = function (request) {
    if (request.method === 'POST') {
        return {
            'statusCode': 201,
            'header': {
                "x-object-callback": ["test_object_callback_header"]
            },
            'body': "an_object_callback_response"
        };
    } else {
        return {
            'statusCode': 404
        };
    }
};
mockServerClient("localhost", 1080)
    .mockWithCallback(
        {
            'path': '/some/path'
        },
        callback
    )
    .then(
        function () {
            console.log("expectation created");
        },
        function (error) {
            console.log(error);
        }
    );

When using org.mockserver.client.MockServerClient each method / closure callback has a separate web socket client. To ensure the number of total threads does not grow too large for large numbers of method / closure callback expectations the default event loop thread pool for the web socket client is kept fairly low. However, if an extremely large load is matched against a single method / closure callback expectation the event loop thread pool may not be large enough for its web socket client.

The number of threads for the event loop thread pool for each web socket client (i.e. for each expectation with a method / closure callback) can be configured and is described in the configuration section.

MockServer provides an in-memory file store that can be used with the FileBody type. Files stored via the file store API can be referenced in expectations by name. The file store is cleared when MockServer is reset.

# Store a file
curl -v -X PUT "http://localhost:1080/mockserver/files/store?name=sample.json" \
    -H "Content-Type: application/json" \
    -d '{"id": 1, "name": "example"}'

# Retrieve a file
curl -v -X PUT "http://localhost:1080/mockserver/files/retrieve" \
    -H "Content-Type: application/json" \
    -d '{"name": "sample.json"}'

# List all stored files
curl -v -X PUT "http://localhost:1080/mockserver/files/list"

# Delete a file
curl -v -X PUT "http://localhost:1080/mockserver/files/delete" \
    -H "Content-Type: application/json" \
    -d '{"name": "sample.json"}'
MockServerClient mockServerClient = new MockServerClient("localhost", 1080);

// Store a file, then reference it in an expectation using FileBody
mockServerClient
    .when(
        request()
            .withPath("/api/data")
    )
    .respond(
        response()
            .withBodyFromFile("sample.json", MediaType.APPLICATION_JSON)
    );

Endpoints:

  • PUT /mockserver/files/store?name=<filename> — stores a file with the given name; the request body is the file content
  • PUT /mockserver/files/retrieve — retrieves a stored file; the request body is a JSON object with a "name" field
  • PUT /mockserver/files/list — lists all stored file names
  • PUT /mockserver/files/delete — deletes a stored file; the request body is a JSON object with a "name" field
new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/some/path")
    )
    .respond(
        new ExpectationResponseCallback() {
            @Override
            public HttpResponse handle(HttpRequest httpRequest) throws Exception {
                if (httpRequest.getMethod().getValue().equals("POST")) {
                    mockServerClient
                        .when(
                            request()
                                .withPath("/some/otherPath")
                        )
                        .respond(
                            response()
                                .withBody(httpRequest.getBodyAsString())
                        );
                    return response()
                        .withStatusCode(ACCEPTED_202.code())
                        .withBody("request processed");
                } else {
                    return notFoundResponse();
                }
            }
        }
    );
new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/some/path")
    )
    .respond(
        httpRequest -> {
            if (httpRequest.getMethod().getValue().equals("POST")) {
                mockServerClient
                    .when(
                        request()
                            .withPath("/some/otherPath")
                    )
                    .respond(
                        response()
                            .withBody(httpRequest.getBodyAsString())
                    );
                return response()
                    .withStatusCode(ACCEPTED_202.code())
                    .withBody("request processed");
            } else {
                return notFoundResponse();
            }
        }
    );
var mockServerClient = require('mockserver-client').mockServerClient;
var callback = function (request) {
    if (request.method === 'POST') {
        mockServerClient("localhost", 1080)
            .mockAnyResponse({
                "httpRequest": {
                    "path": "/some/otherPath"
                },
                "httpResponse": {
                    "body": request.body.string
                }
            })
            .then(
                function () {
                    console.log("chained expectation created");
                },
                function (error) {
                    console.log(error);
                }
            );
        return {
            'statusCode': 202,
            'body': "request processed"
        };
    } else {
        return {
            'statusCode': 404
        };
    }
};
mockServerClient("localhost", 1080)
    .mockWithCallback(
        {
            'path': '/some/path'
        },
        callback
    )
    .then(
        function () {
            console.log("expectation created");
        },
        function (error) {
            console.log(error);
        }
    );

When using org.mockserver.client.MockServerClient each method / closure callback has a separate web socket client. To ensure the number of total threads does not grow too large for large numbers of method / closure callback expectations the default event loop thread pool for the web socket client is kept fairly low. However, if an extremely large load is matched against a single method / closure callback expectation the event loop thread pool may not be large enough for its web socket client.

The number of threads for the event loop thread pool for each web socket client (i.e. for each expectation with a method / closure callback) can be configured and is described in the configuration section.

Add a recoverAfter clause to a response to make it fail for the first failTimes matches and then return the configured success response. This is useful for deterministically testing a client's retry / backoff behaviour against a dependency that fails transiently and then recovers. When no failResponse is given, the failing attempts return a default 503 Service Unavailable. Counting is independent of Times, so a failing attempt does not consume a Times use and the expectation keeps matching across the whole failure window.

# fail the first 3 matches with the default 503, then return the 200 response
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpResponse": {
        "statusCode": 200,
        "body": "ok",
        "recoverAfter": {
            "failTimes": 3
        }
    }
}'

An optional failResponse sets the response returned while failing, and an optional idempotencyHeader scopes the failure window per request header value — each distinct value gets its own independent "fail N then succeed" sequence, while requests carrying the same value share one window (when the header is configured but absent on a request, the per-expectation match count is used instead):

# fail the first 3 attempts per Idempotency-Key value with a custom 503 (incl. Retry-After), then succeed
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpResponse": {
        "statusCode": 200,
        "body": "ok",
        "recoverAfter": {
            "failTimes": 3,
            "failResponse": {
                "statusCode": 503,
                "headers": {
                    "Retry-After": [ "1" ]
                }
            },
            "idempotencyHeader": "Idempotency-Key"
        }
    }
}'

See REST API for full JSON specification

 

A forward action can be:

  • either an exact forwarder, that forwards requests exactly as it receives them, containing the following:

  • or an overridden request (or overridden response), with a delay (including distribution-based delays), that allows any part of a forwarded request or response to be replaced or certain fields (path, headers, cookies or query parameters) to be modified

  • or a templated forwarder using javascript or velocity, with a delay, that allows requests to be modified or completely re-written before they are forwarded

  • or a callback used to dynamically generate the request to forward based on the request received by MockServer:

    • as a server side callback implemented as a java class that has a default constructor, implements org.mockserver.mock.action.ExpectationForwardCallback or org.mockserver.mock.action.ExpectationForwardAndResponseCallback and is available on the classpath

    • as a client side callback implemented as a closure using the java or javascript clients

The following code examples show how to create different forward actions.

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/some/path")
    )
    .forward(
        forward()
            .withHost("mock-server.com")
            .withPort(80)
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "path": "/some/path"
    },
    "httpForward": {
        "host": "mock-server.com",
        "port": 80,
        "scheme": "HTTP"
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import HttpForward, HttpRequest

client = MockServerClient("localhost", 1080)
client.when(
    HttpRequest.request("/some/path")
).forward(
    HttpForward(host="mock-server.com", port=80, scheme="HTTP")
)
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.when(
    MockServer::HttpRequest.new(path: '/some/path')
).forward(
    MockServer::HttpForward.new(host: 'mock-server.com', port: 80, scheme: 'HTTP')
)
import mockserver "github.com/mock-server/mockserver-monorepo/mockserver-client-go"

client := mockserver.New("localhost", 1080)
client.When(
    mockserver.Request().Path("/some/path"),
).Forward(
    mockserver.Forward().Host("mock-server.com").Port(80).Scheme("HTTP"),
)
using MockServer.Client;
using MockServer.Client.Models;

using var client = new MockServerClient("localhost", 1080);
client.When(
    HttpRequest.Request().WithPath("/some/path")
).Forward(
    HttpForward.Forward().WithHost("mock-server.com").WithPort(80).WithScheme("HTTP")
);
use mockserver_client::{ClientBuilder, HttpRequest, HttpForward};

let client = ClientBuilder::new("localhost", 1080).build().unwrap();
client.when(HttpRequest::new().path("/some/path"))
    .forward(HttpForward::new("mock-server.com", 80).scheme("HTTP"))
    .unwrap();
use MockServer\MockServerClient;
use MockServer\HttpRequest;
use MockServer\HttpForward;

$client = new MockServerClient('localhost', 1080);
$client->when(
    HttpRequest::request()
        ->path('/some/path')
)->forward(
    HttpForward::forward()
        ->host('mock-server.com')
        ->port(80)
        ->scheme('HTTP')
);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpForward": {
        "host": "mock-server.com",
        "port": 80,
        "scheme": "HTTP"
    }
}'

See REST API for full JSON specification

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/some/path")
    )
    .forward(
        forward()
            .withHost("mock-server.com")
            .withPort(443)
            .withScheme(HttpForward.Scheme.HTTPS)
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "path": "/some/path"
    },
    "httpForward": {
        "host": "mock-server.com",
        "port": 443,
        "scheme": "HTTPS"
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import HttpForward, HttpRequest

client = MockServerClient("localhost", 1080)
client.when(
    HttpRequest.request("/some/path")
).forward(
    HttpForward(host="mock-server.com", port=443, scheme="HTTPS")
)
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.when(
    MockServer::HttpRequest.new(path: '/some/path')
).forward(
    MockServer::HttpForward.new(host: 'mock-server.com', port: 443, scheme: 'HTTPS')
)
import mockserver "github.com/mock-server/mockserver-monorepo/mockserver-client-go"

client := mockserver.New("localhost", 1080)
client.When(
    mockserver.Request().Path("/some/path"),
).Forward(
    mockserver.Forward().Host("mock-server.com").Port(443).Scheme("HTTPS"),
)
using MockServer.Client;
using MockServer.Client.Models;

using var client = new MockServerClient("localhost", 1080);
client.When(
    HttpRequest.Request().WithPath("/some/path")
).Forward(
    HttpForward.Forward().WithHost("mock-server.com").WithPort(443).WithScheme("HTTPS")
);
use mockserver_client::{ClientBuilder, HttpRequest, HttpForward};

let client = ClientBuilder::new("localhost", 1080).build().unwrap();
client.when(HttpRequest::new().path("/some/path"))
    .forward(HttpForward::new("mock-server.com", 443).scheme("HTTPS"))
    .unwrap();
use MockServer\MockServerClient;
use MockServer\HttpRequest;
use MockServer\HttpForward;

$client = new MockServerClient('localhost', 1080);
$client->when(
    HttpRequest::request()
        ->path('/some/path')
)->forward(
    HttpForward::forward()
        ->host('mock-server.com')
        ->port(443)
        ->scheme('HTTPS')
);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpForward": {
        "host": "mock-server.com",
        "port": 443,
        "scheme": "HTTPS"
    }
}'

See REST API for full JSON specification

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/some/path")
    )
    .forward(
        forwardOverriddenRequest(
            request()
                .withPath("/some/other/path")
                .withHeader("Host", "target.host.com")
        )
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "path": "/some/path"
    },
    "httpOverrideForwardedRequest": {
        "httpRequest": {
            "path": "/some/other/path",
            "headers": {
                "Host": ["target.host.com"]
            }
        }
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import Expectation

client = MockServerClient("localhost", 1080)
client.upsert(Expectation.from_dict({
    "httpRequest": {
        "path": "/some/path"
    },
    "httpOverrideForwardedRequest": {
        "httpRequest": {
            "path": "/some/other/path",
            "headers": {
                "Host": ["target.host.com"]
            }
        }
    }
}))
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.upsert(MockServer::Expectation.from_hash({
    "httpRequest": {
        "path": "/some/path"
    },
    "httpOverrideForwardedRequest": {
        "httpRequest": {
            "path": "/some/other/path",
            "headers": {
                "Host": ["target.host.com"]
            }
        }
    }
}))
package main

import (
    "bytes"
    "net/http"
)

func main() {
    body := []byte(`{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpOverrideForwardedRequest": {
        "httpRequest": {
            "path": "/some/other/path",
            "headers": {
                "Host": ["target.host.com"]
            }
        }
    }
}`)
    req, _ := http.NewRequest("PUT",
        "http://localhost:1080/mockserver/expectation",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    http.DefaultClient.Do(req)
}
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
    ""httpRequest"": {
        ""path"": ""/some/path""
    },
    ""httpOverrideForwardedRequest"": {
        ""httpRequest"": {
            ""path"": ""/some/other/path"",
            ""headers"": {
                ""Host"": [""target.host.com""]
            }
        }
    }
}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpOverrideForwardedRequest": {
        "httpRequest": {
            "path": "/some/other/path",
            "headers": {
                "Host": ["target.host.com"]
            }
        }
    }
}"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
$json = <<<'JSON'
{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpOverrideForwardedRequest": {
        "httpRequest": {
            "path": "/some/other/path",
            "headers": {
                "Host": ["target.host.com"]
            }
        }
    }
}
JSON;

$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_POSTFIELDS     => $json,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json; charset=utf-8'],
    CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
curl_close($ch);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpOverrideForwardedRequest": {
        "httpRequest": {
            "path": "/some/other/path",
            "headers": {
                "Host": ["target.host.com"]
            }
        }
    }
}'

See REST API for full JSON specification

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/some/path")
    )
    .forward(
        forwardOverriddenRequest(
            request()
                .withPath("/some/other/path")
                .withHeader("Host", "target.host.com"),
            response()
                .withBody("some_overridden_body")
        )
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "path": "/some/path"
    },
    "httpOverrideForwardedRequest": {
        "httpRequest": {
            "path": "/some/other/path",
            "headers": {
                "Host": ["target.host.com"]
            }
        },
        "httpResponse": {
            "body": "some_overridden_body"
        }
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import Expectation

client = MockServerClient("localhost", 1080)
client.upsert(Expectation.from_dict({
    "httpRequest": {
        "path": "/some/path"
    },
    "httpOverrideForwardedRequest": {
        "httpRequest": {
            "path": "/some/other/path",
            "headers": {
                "Host": ["target.host.com"]
            }
        },
        "httpResponse": {
            "body": "some_overridden_body"
        }
    }
}))
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.upsert(MockServer::Expectation.from_hash({
    "httpRequest": {
        "path": "/some/path"
    },
    "httpOverrideForwardedRequest": {
        "httpRequest": {
            "path": "/some/other/path",
            "headers": {
                "Host": ["target.host.com"]
            }
        },
        "httpResponse": {
            "body": "some_overridden_body"
        }
    }
}))
package main

import (
    "bytes"
    "net/http"
)

func main() {
    body := []byte(`{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpOverrideForwardedRequest": {
        "httpRequest": {
            "path": "/some/other/path",
            "headers": {
                "Host": ["target.host.com"]
            }
        },
        "httpResponse": {
            "body": "some_overridden_body"
        }
    }
}`)
    req, _ := http.NewRequest("PUT",
        "http://localhost:1080/mockserver/expectation",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    http.DefaultClient.Do(req)
}
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
    ""httpRequest"": {
        ""path"": ""/some/path""
    },
    ""httpOverrideForwardedRequest"": {
        ""httpRequest"": {
            ""path"": ""/some/other/path"",
            ""headers"": {
                ""Host"": [""target.host.com""]
            }
        },
        ""httpResponse"": {
            ""body"": ""some_overridden_body""
        }
    }
}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpOverrideForwardedRequest": {
        "httpRequest": {
            "path": "/some/other/path",
            "headers": {
                "Host": ["target.host.com"]
            }
        },
        "httpResponse": {
            "body": "some_overridden_body"
        }
    }
}"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
$json = <<<'JSON'
{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpOverrideForwardedRequest": {
        "httpRequest": {
            "path": "/some/other/path",
            "headers": {
                "Host": ["target.host.com"]
            }
        },
        "httpResponse": {
            "body": "some_overridden_body"
        }
    }
}
JSON;

$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_POSTFIELDS     => $json,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json; charset=utf-8'],
    CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
curl_close($ch);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpOverrideForwardedRequest": {
        "httpRequest": {
            "path": "/some/other/path",
            "headers": {
                "Host": ["target.host.com"]
            }
        },
        "httpResponse": {
            "body": "some_overridden_body"
        }
    }
}'

See REST API for full JSON specification

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/some/path")
    )
    .forward(
        forwardOverriddenRequest(
            request()
                // this replaces the entire set of headers
                .withHeader("Host", "target.host.com")
                .withBody("some_overridden_body"),
            requestModifier()
                .withPath("^/(.+)/(.+)$", "/prefix/$1/infix/$2/postfix")
                .withQueryStringParameters(
                    queryParametersModifier()
                        .add(
                            param("parameterToAddOne", "addedValue"),
                            param("parameterToAddTwo", "addedValue")
                        )
                        .replace(
                            param("overrideParameterToReplace", "replacedValue"),
                            param("requestParameterToReplace", "replacedValue"),
                            param("extraParameterToReplace", "shouldBeIgnore")
                        )
                        .remove(
                            "overrideParameterToRemove",
                            "requestParameterToRemove"
                        )

                )
                // this modifies the set of headers
                .withHeaders(
                    headersModifier()
                        .add(
                            header("headerToAddOne", "addedValue"),
                            header("headerToAddTwo", "addedValue")
                        )
                        .replace(
                            header("overrideHeaderToReplace", "replacedValue"),
                            header("requestHeaderToReplace", "replacedValue"),
                            header("extraHeaderToReplace", "shouldBeIgnore")
                        )
                        .remove(
                            "overrideHeaderToRemove",
                            "requestHeaderToRemove"
                        )

                )
                .withCookies(
                    cookiesModifier()
                        .add(
                            cookie("cookieToAddOne", "addedValue"),
                            cookie("cookieToAddTwo", "addedValue")
                        )
                        .replace(
                            cookie("overrideCookieToReplace", "replacedValue"),
                            cookie("requestCookieToReplace", "replacedValue"),
                            cookie("extraCookieToReplace", "shouldBeIgnore")
                        )
                        .remove(
                            "overrideCookieToRemove",
                            "requestCookieToRemove"
                        )

                )
        )
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "path": "/some/path"
    },
    "httpOverrideForwardedRequest": {
        "requestOverride": {
            "headers": {
                "Host": [
                    "target.host.com"
                ]
            },
            "body": "some_overridden_body"
        },
        "requestModifier": {
            "cookies": {
                "add": {
                    "cookieToAddOne": "addedValue",
                    "cookieToAddTwo": "addedValue"
                },
                "remove": [
                    "overrideCookieToRemove",
                    "requestCookieToRemove"
                ],
                "replace": {
                    "overrideCookieToReplace": "replacedValue",
                    "requestCookieToReplace": "replacedValue",
                    "extraCookieToReplace": "shouldBeIgnore"
                }
            },
            "headers": {
                "add": {
                    "headerToAddTwo": [
                        "addedValue"
                    ],
                    "headerToAddOne": [
                        "addedValue"
                    ]
                },
                "remove": [
                    "overrideHeaderToRemove",
                    "requestHeaderToRemove"
                ],
                "replace": {
                    "requestHeaderToReplace": [
                        "replacedValue"
                    ],
                    "overrideHeaderToReplace": [
                        "replacedValue"
                    ],
                    "extraHeaderToReplace": [
                        "shouldBeIgnore"
                    ]
                }
            },
            "path": {
                "regex": "^/(.+)/(.+)$",
                "substitution": "/prefix/$1/infix/$2/postfix"
            },
            "queryStringParameters": {
                "add": {
                    "parameterToAddTwo": [
                        "addedValue"
                    ],
                    "parameterToAddOne": [
                        "addedValue"
                    ]
                },
                "remove": [
                    "overrideParameterToRemove",
                    "requestParameterToRemove"
                ],
                "replace": {
                    "requestParameterToReplace": [
                        "replacedValue"
                    ],
                    "overrideParameterToReplace": [
                        "replacedValue"
                    ],
                    "extraParameterToReplace": [
                        "shouldBeIgnore"
                    ]
                }
            }
        }
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import Expectation

client = MockServerClient("localhost", 1080)
client.upsert(Expectation.from_dict({
    "httpRequest": {
        "path": "/some/path"
    },
    "httpOverrideForwardedRequest": {
        "requestOverride": {
            "headers": {
                "Host": [
                    "target.host.com"
                ]
            },
            "body": "some_overridden_body"
        },
        "requestModifier": {
            "cookies": {
                "add": {
                    "cookieToAddOne": "addedValue",
                    "cookieToAddTwo": "addedValue"
                },
                "remove": [
                    "overrideCookieToRemove",
                    "requestCookieToRemove"
                ],
                "replace": {
                    "overrideCookieToReplace": "replacedValue",
                    "requestCookieToReplace": "replacedValue",
                    "extraCookieToReplace": "shouldBeIgnore"
                }
            },
            "headers": {
                "add": {
                    "headerToAddTwo": [
                        "addedValue"
                    ],
                    "headerToAddOne": [
                        "addedValue"
                    ]
                },
                "remove": [
                    "overrideHeaderToRemove",
                    "requestHeaderToRemove"
                ],
                "replace": {
                    "requestHeaderToReplace": [
                        "replacedValue"
                    ],
                    "overrideHeaderToReplace": [
                        "replacedValue"
                    ],
                    "extraHeaderToReplace": [
                        "shouldBeIgnore"
                    ]
                }
            },
            "path": {
                "regex": "^/(.+)/(.+)$",
                "substitution": "/prefix/$1/infix/$2/postfix"
            },
            "queryStringParameters": {
                "add": {
                    "parameterToAddTwo": [
                        "addedValue"
                    ],
                    "parameterToAddOne": [
                        "addedValue"
                    ]
                },
                "remove": [
                    "overrideParameterToRemove",
                    "requestParameterToRemove"
                ],
                "replace": {
                    "requestParameterToReplace": [
                        "replacedValue"
                    ],
                    "overrideParameterToReplace": [
                        "replacedValue"
                    ],
                    "extraParameterToReplace": [
                        "shouldBeIgnore"
                    ]
                }
            }
        }
    }
}))
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.upsert(MockServer::Expectation.from_hash({
    "httpRequest": {
        "path": "/some/path"
    },
    "httpOverrideForwardedRequest": {
        "requestOverride": {
            "headers": {
                "Host": [
                    "target.host.com"
                ]
            },
            "body": "some_overridden_body"
        },
        "requestModifier": {
            "cookies": {
                "add": {
                    "cookieToAddOne": "addedValue",
                    "cookieToAddTwo": "addedValue"
                },
                "remove": [
                    "overrideCookieToRemove",
                    "requestCookieToRemove"
                ],
                "replace": {
                    "overrideCookieToReplace": "replacedValue",
                    "requestCookieToReplace": "replacedValue",
                    "extraCookieToReplace": "shouldBeIgnore"
                }
            },
            "headers": {
                "add": {
                    "headerToAddTwo": [
                        "addedValue"
                    ],
                    "headerToAddOne": [
                        "addedValue"
                    ]
                },
                "remove": [
                    "overrideHeaderToRemove",
                    "requestHeaderToRemove"
                ],
                "replace": {
                    "requestHeaderToReplace": [
                        "replacedValue"
                    ],
                    "overrideHeaderToReplace": [
                        "replacedValue"
                    ],
                    "extraHeaderToReplace": [
                        "shouldBeIgnore"
                    ]
                }
            },
            "path": {
                "regex": "^/(.+)/(.+)$",
                "substitution": "/prefix/$1/infix/$2/postfix"
            },
            "queryStringParameters": {
                "add": {
                    "parameterToAddTwo": [
                        "addedValue"
                    ],
                    "parameterToAddOne": [
                        "addedValue"
                    ]
                },
                "remove": [
                    "overrideParameterToRemove",
                    "requestParameterToRemove"
                ],
                "replace": {
                    "requestParameterToReplace": [
                        "replacedValue"
                    ],
                    "overrideParameterToReplace": [
                        "replacedValue"
                    ],
                    "extraParameterToReplace": [
                        "shouldBeIgnore"
                    ]
                }
            }
        }
    }
}))
package main

import (
    "bytes"
    "net/http"
)

func main() {
    body := []byte(`{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpOverrideForwardedRequest": {
        "requestOverride": {
            "headers": {
                "Host": [
                    "target.host.com"
                ]
            },
            "body": "some_overridden_body"
        },
        "requestModifier": {
            "cookies": {
                "add": {
                    "cookieToAddOne": "addedValue",
                    "cookieToAddTwo": "addedValue"
                },
                "remove": [
                    "overrideCookieToRemove",
                    "requestCookieToRemove"
                ],
                "replace": {
                    "overrideCookieToReplace": "replacedValue",
                    "requestCookieToReplace": "replacedValue",
                    "extraCookieToReplace": "shouldBeIgnore"
                }
            },
            "headers": {
                "add": {
                    "headerToAddTwo": [
                        "addedValue"
                    ],
                    "headerToAddOne": [
                        "addedValue"
                    ]
                },
                "remove": [
                    "overrideHeaderToRemove",
                    "requestHeaderToRemove"
                ],
                "replace": {
                    "requestHeaderToReplace": [
                        "replacedValue"
                    ],
                    "overrideHeaderToReplace": [
                        "replacedValue"
                    ],
                    "extraHeaderToReplace": [
                        "shouldBeIgnore"
                    ]
                }
            },
            "path": {
                "regex": "^/(.+)/(.+)$",
                "substitution": "/prefix/$1/infix/$2/postfix"
            },
            "queryStringParameters": {
                "add": {
                    "parameterToAddTwo": [
                        "addedValue"
                    ],
                    "parameterToAddOne": [
                        "addedValue"
                    ]
                },
                "remove": [
                    "overrideParameterToRemove",
                    "requestParameterToRemove"
                ],
                "replace": {
                    "requestParameterToReplace": [
                        "replacedValue"
                    ],
                    "overrideParameterToReplace": [
                        "replacedValue"
                    ],
                    "extraParameterToReplace": [
                        "shouldBeIgnore"
                    ]
                }
            }
        }
    }
}`)
    req, _ := http.NewRequest("PUT",
        "http://localhost:1080/mockserver/expectation",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    http.DefaultClient.Do(req)
}
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
    ""httpRequest"": {
        ""path"": ""/some/path""
    },
    ""httpOverrideForwardedRequest"": {
        ""requestOverride"": {
            ""headers"": {
                ""Host"": [
                    ""target.host.com""
                ]
            },
            ""body"": ""some_overridden_body""
        },
        ""requestModifier"": {
            ""cookies"": {
                ""add"": {
                    ""cookieToAddOne"": ""addedValue"",
                    ""cookieToAddTwo"": ""addedValue""
                },
                ""remove"": [
                    ""overrideCookieToRemove"",
                    ""requestCookieToRemove""
                ],
                ""replace"": {
                    ""overrideCookieToReplace"": ""replacedValue"",
                    ""requestCookieToReplace"": ""replacedValue"",
                    ""extraCookieToReplace"": ""shouldBeIgnore""
                }
            },
            ""headers"": {
                ""add"": {
                    ""headerToAddTwo"": [
                        ""addedValue""
                    ],
                    ""headerToAddOne"": [
                        ""addedValue""
                    ]
                },
                ""remove"": [
                    ""overrideHeaderToRemove"",
                    ""requestHeaderToRemove""
                ],
                ""replace"": {
                    ""requestHeaderToReplace"": [
                        ""replacedValue""
                    ],
                    ""overrideHeaderToReplace"": [
                        ""replacedValue""
                    ],
                    ""extraHeaderToReplace"": [
                        ""shouldBeIgnore""
                    ]
                }
            },
            ""path"": {
                ""regex"": ""^/(.+)/(.+)$"",
                ""substitution"": ""/prefix/$1/infix/$2/postfix""
            },
            ""queryStringParameters"": {
                ""add"": {
                    ""parameterToAddTwo"": [
                        ""addedValue""
                    ],
                    ""parameterToAddOne"": [
                        ""addedValue""
                    ]
                },
                ""remove"": [
                    ""overrideParameterToRemove"",
                    ""requestParameterToRemove""
                ],
                ""replace"": {
                    ""requestParameterToReplace"": [
                        ""replacedValue""
                    ],
                    ""overrideParameterToReplace"": [
                        ""replacedValue""
                    ],
                    ""extraParameterToReplace"": [
                        ""shouldBeIgnore""
                    ]
                }
            }
        }
    }
}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpOverrideForwardedRequest": {
        "requestOverride": {
            "headers": {
                "Host": [
                    "target.host.com"
                ]
            },
            "body": "some_overridden_body"
        },
        "requestModifier": {
            "cookies": {
                "add": {
                    "cookieToAddOne": "addedValue",
                    "cookieToAddTwo": "addedValue"
                },
                "remove": [
                    "overrideCookieToRemove",
                    "requestCookieToRemove"
                ],
                "replace": {
                    "overrideCookieToReplace": "replacedValue",
                    "requestCookieToReplace": "replacedValue",
                    "extraCookieToReplace": "shouldBeIgnore"
                }
            },
            "headers": {
                "add": {
                    "headerToAddTwo": [
                        "addedValue"
                    ],
                    "headerToAddOne": [
                        "addedValue"
                    ]
                },
                "remove": [
                    "overrideHeaderToRemove",
                    "requestHeaderToRemove"
                ],
                "replace": {
                    "requestHeaderToReplace": [
                        "replacedValue"
                    ],
                    "overrideHeaderToReplace": [
                        "replacedValue"
                    ],
                    "extraHeaderToReplace": [
                        "shouldBeIgnore"
                    ]
                }
            },
            "path": {
                "regex": "^/(.+)/(.+)$",
                "substitution": "/prefix/$1/infix/$2/postfix"
            },
            "queryStringParameters": {
                "add": {
                    "parameterToAddTwo": [
                        "addedValue"
                    ],
                    "parameterToAddOne": [
                        "addedValue"
                    ]
                },
                "remove": [
                    "overrideParameterToRemove",
                    "requestParameterToRemove"
                ],
                "replace": {
                    "requestParameterToReplace": [
                        "replacedValue"
                    ],
                    "overrideParameterToReplace": [
                        "replacedValue"
                    ],
                    "extraParameterToReplace": [
                        "shouldBeIgnore"
                    ]
                }
            }
        }
    }
}"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
$json = <<<'JSON'
{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpOverrideForwardedRequest": {
        "requestOverride": {
            "headers": {
                "Host": [
                    "target.host.com"
                ]
            },
            "body": "some_overridden_body"
        },
        "requestModifier": {
            "cookies": {
                "add": {
                    "cookieToAddOne": "addedValue",
                    "cookieToAddTwo": "addedValue"
                },
                "remove": [
                    "overrideCookieToRemove",
                    "requestCookieToRemove"
                ],
                "replace": {
                    "overrideCookieToReplace": "replacedValue",
                    "requestCookieToReplace": "replacedValue",
                    "extraCookieToReplace": "shouldBeIgnore"
                }
            },
            "headers": {
                "add": {
                    "headerToAddTwo": [
                        "addedValue"
                    ],
                    "headerToAddOne": [
                        "addedValue"
                    ]
                },
                "remove": [
                    "overrideHeaderToRemove",
                    "requestHeaderToRemove"
                ],
                "replace": {
                    "requestHeaderToReplace": [
                        "replacedValue"
                    ],
                    "overrideHeaderToReplace": [
                        "replacedValue"
                    ],
                    "extraHeaderToReplace": [
                        "shouldBeIgnore"
                    ]
                }
            },
            "path": {
                "regex": "^/(.+)/(.+)$",
                "substitution": "/prefix/$1/infix/$2/postfix"
            },
            "queryStringParameters": {
                "add": {
                    "parameterToAddTwo": [
                        "addedValue"
                    ],
                    "parameterToAddOne": [
                        "addedValue"
                    ]
                },
                "remove": [
                    "overrideParameterToRemove",
                    "requestParameterToRemove"
                ],
                "replace": {
                    "requestParameterToReplace": [
                        "replacedValue"
                    ],
                    "overrideParameterToReplace": [
                        "replacedValue"
                    ],
                    "extraParameterToReplace": [
                        "shouldBeIgnore"
                    ]
                }
            }
        }
    }
}
JSON;

$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_POSTFIELDS     => $json,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json; charset=utf-8'],
    CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
curl_close($ch);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpOverrideForwardedRequest": {
        "requestOverride": {
            "headers": {
                "Host": [
                    "target.host.com"
                ]
            },
            "body": "some_overridden_body"
        },
        "requestModifier": {
            "cookies": {
                "add": {
                    "cookieToAddOne": "addedValue",
                    "cookieToAddTwo": "addedValue"
                },
                "remove": [
                    "overrideCookieToRemove",
                    "requestCookieToRemove"
                ],
                "replace": {
                    "overrideCookieToReplace": "replacedValue",
                    "requestCookieToReplace": "replacedValue",
                    "extraCookieToReplace": "shouldBeIgnore"
                }
            },
            "headers": {
                "add": {
                    "headerToAddTwo": [
                        "addedValue"
                    ],
                    "headerToAddOne": [
                        "addedValue"
                    ]
                },
                "remove": [
                    "overrideHeaderToRemove",
                    "requestHeaderToRemove"
                ],
                "replace": {
                    "requestHeaderToReplace": [
                        "replacedValue"
                    ],
                    "overrideHeaderToReplace": [
                        "replacedValue"
                    ],
                    "extraHeaderToReplace": [
                        "shouldBeIgnore"
                    ]
                }
            },
            "path": {
                "regex": "^/(.+)/(.+)$",
                "substitution": "/prefix/$1/infix/$2/postfix"
            },
            "queryStringParameters": {
                "add": {
                    "parameterToAddTwo": [
                        "addedValue"
                    ],
                    "parameterToAddOne": [
                        "addedValue"
                    ]
                },
                "remove": [
                    "overrideParameterToRemove",
                    "requestParameterToRemove"
                ],
                "replace": {
                    "requestParameterToReplace": [
                        "replacedValue"
                    ],
                    "overrideParameterToReplace": [
                        "replacedValue"
                    ],
                    "extraParameterToReplace": [
                        "shouldBeIgnore"
                    ]
                }
            }
        }
    }
}'

See REST API for full JSON specification

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/some/path")
    )
    .forward(
        forwardOverriddenRequest()
            .withRequestOverride(
                request()
                    // this replaces the entire set of headers
                    .withHeader("Host", "target.host.com")
                    .withBody("some_overridden_body")
            )
            .withRequestModifier(
                requestModifier()
                    .withPath("^/(.+)/(.+)$", "/prefix/$1/infix/$2/postfix")
                    .withQueryStringParameters(
                        queryParametersModifier()
                            .add(
                                param("parameterToAddOne", "addedValue"),
                                param("parameterToAddTwo", "addedValue")
                            )
                            .replace(
                                param("overrideParameterToReplace", "replacedValue"),
                                param("requestParameterToReplace", "replacedValue"),
                                param("extraParameterToReplace", "shouldBeIgnore")
                            )
                            .remove(
                                "overrideParameterToRemove",
                                "requestParameterToRemove"
                            )

                    )
                    // this modifies the set of headers
                    .withHeaders(
                        headersModifier()
                            .add(
                                header("headerToAddOne", "addedValue"),
                                header("headerToAddTwo", "addedValue")
                            )
                            .replace(
                                header("overrideHeaderToReplace", "replacedValue"),
                                header("requestHeaderToReplace", "replacedValue"),
                                header("extraHeaderToReplace", "shouldBeIgnore")
                            )
                            .remove(
                                "overrideHeaderToRemove",
                                "requestHeaderToRemove"
                            )

                    )
                    .withCookies(
                        cookiesModifier()
                            .add(
                                cookie("cookieToAddOne", "addedValue"),
                                cookie("cookieToAddTwo", "addedValue")
                            )
                            .replace(
                                cookie("overrideCookieToReplace", "replacedValue"),
                                cookie("requestCookieToReplace", "replacedValue"),
                                cookie("extraCookieToReplace", "shouldBeIgnore")
                            )
                            .remove(
                                "overrideCookieToRemove",
                                "requestCookieToRemove"
                            )

                    )
            )
            .withResponseOverride(
                response()
                    .withBody("some_overridden_body")
            )
            .withResponseModifier(
                responseModifier()
                    .withHeaders(
                        headersModifier()
                            .add(
                                header("headerToAddOne", "addedValue"),
                                header("headerToAddTwo", "addedValue")
                            )
                            .replace(
                                header("overrideHeaderToReplace", "replacedValue"),
                                header("requestHeaderToReplace", "replacedValue"),
                                header("extraHeaderToReplace", "shouldBeIgnore")
                            )
                            .remove(
                                "overrideHeaderToRemove",
                                "requestHeaderToRemove"
                            )

                    )
                    .withCookies(
                        cookiesModifier()
                            .add(
                                cookie("cookieToAddOne", "addedValue"),
                                cookie("cookieToAddTwo", "addedValue")
                            )
                            .replace(
                                cookie("overrideCookieToReplace", "replacedValue"),
                                cookie("requestCookieToReplace", "replacedValue"),
                                cookie("extraCookieToReplace", "shouldBeIgnore")
                            )
                            .remove(
                                "overrideCookieToRemove",
                                "requestCookieToRemove"
                            )

                    )
            )
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "path": "/some/path"
    },
    "httpOverrideForwardedRequest": {
        "requestOverride": {
            "headers": {
                "Host": [
                    "target.host.com"
                ]
            },
            "body": "some_overridden_body"
        },
        "requestModifier": {
            "cookies": {
                "add": {
                    "cookieToAddOne": "addedValue",
                    "cookieToAddTwo": "addedValue"
                },
                "remove": [
                    "overrideCookieToRemove",
                    "requestCookieToRemove"
                ],
                "replace": {
                    "overrideCookieToReplace": "replacedValue",
                    "requestCookieToReplace": "replacedValue",
                    "extraCookieToReplace": "shouldBeIgnore"
                }
            },
            "headers": {
                "add": {
                    "headerToAddTwo": [
                        "addedValue"
                    ],
                    "headerToAddOne": [
                        "addedValue"
                    ]
                },
                "remove": [
                    "overrideHeaderToRemove",
                    "requestHeaderToRemove"
                ],
                "replace": {
                    "requestHeaderToReplace": [
                        "replacedValue"
                    ],
                    "overrideHeaderToReplace": [
                        "replacedValue"
                    ],
                    "extraHeaderToReplace": [
                        "shouldBeIgnore"
                    ]
                }
            },
            "path": {
                "regex": "^/(.+)/(.+)$",
                "substitution": "/prefix/$1/infix/$2/postfix"
            },
            "queryStringParameters": {
                "add": {
                    "parameterToAddTwo": [
                        "addedValue"
                    ],
                    "parameterToAddOne": [
                        "addedValue"
                    ]
                },
                "remove": [
                    "overrideParameterToRemove",
                    "requestParameterToRemove"
                ],
                "replace": {
                    "requestParameterToReplace": [
                        "replacedValue"
                    ],
                    "overrideParameterToReplace": [
                        "replacedValue"
                    ],
                    "extraParameterToReplace": [
                        "shouldBeIgnore"
                    ]
                }
            }
        },
        "responseOverride": {
            "body": "some_overridden_body"
        },
        "responseModifier": {
            "cookies": {
                "add": {
                    "cookieToAddOne": "addedValue",
                    "cookieToAddTwo": "addedValue"
                },
                "remove": [
                    "overrideCookieToRemove",
                    "requestCookieToRemove"
                ],
                "replace": {
                    "overrideCookieToReplace": "replacedValue",
                    "requestCookieToReplace": "replacedValue",
                    "extraCookieToReplace": "shouldBeIgnore"
                }
            },
            "headers": {
                "add": {
                    "headerToAddTwo": [
                        "addedValue"
                    ],
                    "headerToAddOne": [
                        "addedValue"
                    ]
                },
                "remove": [
                    "overrideHeaderToRemove",
                    "requestHeaderToRemove"
                ],
                "replace": {
                    "requestHeaderToReplace": [
                        "replacedValue"
                    ],
                    "overrideHeaderToReplace": [
                        "replacedValue"
                    ],
                    "extraHeaderToReplace": [
                        "shouldBeIgnore"
                    ]
                }
            }
        }
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import Expectation

client = MockServerClient("localhost", 1080)
client.upsert(Expectation.from_dict({
    "httpRequest": {
        "path": "/some/path"
    },
    "httpOverrideForwardedRequest": {
        "requestOverride": {
            "headers": {
                "Host": [
                    "target.host.com"
                ]
            },
            "body": "some_overridden_body"
        },
        "requestModifier": {
            "cookies": {
                "add": {
                    "cookieToAddOne": "addedValue",
                    "cookieToAddTwo": "addedValue"
                },
                "remove": [
                    "overrideCookieToRemove",
                    "requestCookieToRemove"
                ],
                "replace": {
                    "overrideCookieToReplace": "replacedValue",
                    "requestCookieToReplace": "replacedValue",
                    "extraCookieToReplace": "shouldBeIgnore"
                }
            },
            "headers": {
                "add": {
                    "headerToAddTwo": [
                        "addedValue"
                    ],
                    "headerToAddOne": [
                        "addedValue"
                    ]
                },
                "remove": [
                    "overrideHeaderToRemove",
                    "requestHeaderToRemove"
                ],
                "replace": {
                    "requestHeaderToReplace": [
                        "replacedValue"
                    ],
                    "overrideHeaderToReplace": [
                        "replacedValue"
                    ],
                    "extraHeaderToReplace": [
                        "shouldBeIgnore"
                    ]
                }
            },
            "path": {
                "regex": "^/(.+)/(.+)$",
                "substitution": "/prefix/$1/infix/$2/postfix"
            },
            "queryStringParameters": {
                "add": {
                    "parameterToAddTwo": [
                        "addedValue"
                    ],
                    "parameterToAddOne": [
                        "addedValue"
                    ]
                },
                "remove": [
                    "overrideParameterToRemove",
                    "requestParameterToRemove"
                ],
                "replace": {
                    "requestParameterToReplace": [
                        "replacedValue"
                    ],
                    "overrideParameterToReplace": [
                        "replacedValue"
                    ],
                    "extraParameterToReplace": [
                        "shouldBeIgnore"
                    ]
                }
            }
        },
        "responseOverride": {
            "body": "some_overridden_body"
        },
        "responseModifier": {
            "cookies": {
                "add": {
                    "cookieToAddOne": "addedValue",
                    "cookieToAddTwo": "addedValue"
                },
                "remove": [
                    "overrideCookieToRemove",
                    "requestCookieToRemove"
                ],
                "replace": {))
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.upsert(MockServer::Expectation.from_hash({
    "httpRequest": {
        "path": "/some/path"
    },
    "httpOverrideForwardedRequest": {
        "requestOverride": {
            "headers": {
                "Host": [
                    "target.host.com"
                ]
            },
            "body": "some_overridden_body"
        },
        "requestModifier": {
            "cookies": {
                "add": {
                    "cookieToAddOne": "addedValue",
                    "cookieToAddTwo": "addedValue"
                },
                "remove": [
                    "overrideCookieToRemove",
                    "requestCookieToRemove"
                ],
                "replace": {
                    "overrideCookieToReplace": "replacedValue",
                    "requestCookieToReplace": "replacedValue",
                    "extraCookieToReplace": "shouldBeIgnore"
                }
            },
            "headers": {
                "add": {
                    "headerToAddTwo": [
                        "addedValue"
                    ],
                    "headerToAddOne": [
                        "addedValue"
                    ]
                },
                "remove": [
                    "overrideHeaderToRemove",
                    "requestHeaderToRemove"
                ],
                "replace": {
                    "requestHeaderToReplace": [
                        "replacedValue"
                    ],
                    "overrideHeaderToReplace": [
                        "replacedValue"
                    ],
                    "extraHeaderToReplace": [
                        "shouldBeIgnore"
                    ]
                }
            },
            "path": {
                "regex": "^/(.+)/(.+)$",
                "substitution": "/prefix/$1/infix/$2/postfix"
            },
            "queryStringParameters": {
                "add": {
                    "parameterToAddTwo": [
                        "addedValue"
                    ],
                    "parameterToAddOne": [
                        "addedValue"
                    ]
                },
                "remove": [
                    "overrideParameterToRemove",
                    "requestParameterToRemove"
                ],
                "replace": {
                    "requestParameterToReplace": [
                        "replacedValue"
                    ],
                    "overrideParameterToReplace": [
                        "replacedValue"
                    ],
                    "extraParameterToReplace": [
                        "shouldBeIgnore"
                    ]
                }
            }
        },
        "responseOverride": {
            "body": "some_overridden_body"
        },
        "responseModifier": {
            "cookies": {
                "add": {
                    "cookieToAddOne": "addedValue",
                    "cookieToAddTwo": "addedValue"
                },
                "remove": [
                    "overrideCookieToRemove",
                    "requestCookieToRemove"
                ],
                "replace": {))
package main

import (
    "bytes"
    "net/http"
)

func main() {
    body := []byte(`{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpOverrideForwardedRequest": {
        "requestOverride": {
            "headers": {
                "Host": [
                    "target.host.com"
                ]
            },
            "body": "some_overridden_body"
        },
        "requestModifier": {
            "cookies": {
                "add": {
                    "cookieToAddOne": "addedValue",
                    "cookieToAddTwo": "addedValue"
                },
                "remove": [
                    "overrideCookieToRemove",
                    "requestCookieToRemove"
                ],
                "replace": {
                    "overrideCookieToReplace": "replacedValue",
                    "requestCookieToReplace": "replacedValue",
                    "extraCookieToReplace": "shouldBeIgnore"
                }
            },
            "headers": {
                "add": {
                    "headerToAddTwo": [
                        "addedValue"
                    ],
                    "headerToAddOne": [
                        "addedValue"
                    ]
                },
                "remove": [
                    "overrideHeaderToRemove",
                    "requestHeaderToRemove"
                ],
                "replace": {
                    "requestHeaderToReplace": [
                        "replacedValue"
                    ],
                    "overrideHeaderToReplace": [
                        "replacedValue"
                    ],
                    "extraHeaderToReplace": [
                        "shouldBeIgnore"
                    ]
                }
            },
            "path": {
                "regex": "^/(.+)/(.+)$",
                "substitution": "/prefix/$1/infix/$2/postfix"
            },
            "queryStringParameters": {
                "add": {
                    "parameterToAddTwo": [
                        "addedValue"
                    ],
                    "parameterToAddOne": [
                        "addedValue"
                    ]
                },
                "remove": [
                    "overrideParameterToRemove",
                    "requestParameterToRemove"
                ],
                "replace": {
                    "requestParameterToReplace": [
                        "replacedValue"
                    ],
                    "overrideParameterToReplace": [
                        "replacedValue"
                    ],
                    "extraParameterToReplace": [
                        "shouldBeIgnore"
                    ]
                }
            }
        },
        "responseOverride": {
            "body": "some_overridden_body"
        },
        "responseModifier": {
            "cookies": {
                "add": {
                    "cookieToAddOne": "addedValue",
                    "cookieToAddTwo": "addedValue"
                },
                "remove": [
                    "overrideCookieToRemove",
                    "requestCookieToRemove"
                ],
                "replace": {`)
    req, _ := http.NewRequest("PUT",
        "http://localhost:1080/mockserver/expectation",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    http.DefaultClient.Do(req)
}
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
    ""httpRequest"": {
        ""path"": ""/some/path""
    },
    ""httpOverrideForwardedRequest"": {
        ""requestOverride"": {
            ""headers"": {
                ""Host"": [
                    ""target.host.com""
                ]
            },
            ""body"": ""some_overridden_body""
        },
        ""requestModifier"": {
            ""cookies"": {
                ""add"": {
                    ""cookieToAddOne"": ""addedValue"",
                    ""cookieToAddTwo"": ""addedValue""
                },
                ""remove"": [
                    ""overrideCookieToRemove"",
                    ""requestCookieToRemove""
                ],
                ""replace"": {
                    ""overrideCookieToReplace"": ""replacedValue"",
                    ""requestCookieToReplace"": ""replacedValue"",
                    ""extraCookieToReplace"": ""shouldBeIgnore""
                }
            },
            ""headers"": {
                ""add"": {
                    ""headerToAddTwo"": [
                        ""addedValue""
                    ],
                    ""headerToAddOne"": [
                        ""addedValue""
                    ]
                },
                ""remove"": [
                    ""overrideHeaderToRemove"",
                    ""requestHeaderToRemove""
                ],
                ""replace"": {
                    ""requestHeaderToReplace"": [
                        ""replacedValue""
                    ],
                    ""overrideHeaderToReplace"": [
                        ""replacedValue""
                    ],
                    ""extraHeaderToReplace"": [
                        ""shouldBeIgnore""
                    ]
                }
            },
            ""path"": {
                ""regex"": ""^/(.+)/(.+)$"",
                ""substitution"": ""/prefix/$1/infix/$2/postfix""
            },
            ""queryStringParameters"": {
                ""add"": {
                    ""parameterToAddTwo"": [
                        ""addedValue""
                    ],
                    ""parameterToAddOne"": [
                        ""addedValue""
                    ]
                },
                ""remove"": [
                    ""overrideParameterToRemove"",
                    ""requestParameterToRemove""
                ],
                ""replace"": {
                    ""requestParameterToReplace"": [
                        ""replacedValue""
                    ],
                    ""overrideParameterToReplace"": [
                        ""replacedValue""
                    ],
                    ""extraParameterToReplace"": [
                        ""shouldBeIgnore""
                    ]
                }
            }
        },
        ""responseOverride"": {
            ""body"": ""some_overridden_body""
        },
        ""responseModifier"": {
            ""cookies"": {
                ""add"": {
                    ""cookieToAddOne"": ""addedValue"",
                    ""cookieToAddTwo"": ""addedValue""
                },
                ""remove"": [
                    ""overrideCookieToRemove"",
                    ""requestCookieToRemove""
                ],
                ""replace"": {";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpOverrideForwardedRequest": {
        "requestOverride": {
            "headers": {
                "Host": [
                    "target.host.com"
                ]
            },
            "body": "some_overridden_body"
        },
        "requestModifier": {
            "cookies": {
                "add": {
                    "cookieToAddOne": "addedValue",
                    "cookieToAddTwo": "addedValue"
                },
                "remove": [
                    "overrideCookieToRemove",
                    "requestCookieToRemove"
                ],
                "replace": {
                    "overrideCookieToReplace": "replacedValue",
                    "requestCookieToReplace": "replacedValue",
                    "extraCookieToReplace": "shouldBeIgnore"
                }
            },
            "headers": {
                "add": {
                    "headerToAddTwo": [
                        "addedValue"
                    ],
                    "headerToAddOne": [
                        "addedValue"
                    ]
                },
                "remove": [
                    "overrideHeaderToRemove",
                    "requestHeaderToRemove"
                ],
                "replace": {
                    "requestHeaderToReplace": [
                        "replacedValue"
                    ],
                    "overrideHeaderToReplace": [
                        "replacedValue"
                    ],
                    "extraHeaderToReplace": [
                        "shouldBeIgnore"
                    ]
                }
            },
            "path": {
                "regex": "^/(.+)/(.+)$",
                "substitution": "/prefix/$1/infix/$2/postfix"
            },
            "queryStringParameters": {
                "add": {
                    "parameterToAddTwo": [
                        "addedValue"
                    ],
                    "parameterToAddOne": [
                        "addedValue"
                    ]
                },
                "remove": [
                    "overrideParameterToRemove",
                    "requestParameterToRemove"
                ],
                "replace": {
                    "requestParameterToReplace": [
                        "replacedValue"
                    ],
                    "overrideParameterToReplace": [
                        "replacedValue"
                    ],
                    "extraParameterToReplace": [
                        "shouldBeIgnore"
                    ]
                }
            }
        },
        "responseOverride": {
            "body": "some_overridden_body"
        },
        "responseModifier": {
            "cookies": {
                "add": {
                    "cookieToAddOne": "addedValue",
                    "cookieToAddTwo": "addedValue"
                },
                "remove": [
                    "overrideCookieToRemove",
                    "requestCookieToRemove"
                ],
                "replace": {"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
$json = <<<'JSON'
{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpOverrideForwardedRequest": {
        "requestOverride": {
            "headers": {
                "Host": [
                    "target.host.com"
                ]
            },
            "body": "some_overridden_body"
        },
        "requestModifier": {
            "cookies": {
                "add": {
                    "cookieToAddOne": "addedValue",
                    "cookieToAddTwo": "addedValue"
                },
                "remove": [
                    "overrideCookieToRemove",
                    "requestCookieToRemove"
                ],
                "replace": {
                    "overrideCookieToReplace": "replacedValue",
                    "requestCookieToReplace": "replacedValue",
                    "extraCookieToReplace": "shouldBeIgnore"
                }
            },
            "headers": {
                "add": {
                    "headerToAddTwo": [
                        "addedValue"
                    ],
                    "headerToAddOne": [
                        "addedValue"
                    ]
                },
                "remove": [
                    "overrideHeaderToRemove",
                    "requestHeaderToRemove"
                ],
                "replace": {
                    "requestHeaderToReplace": [
                        "replacedValue"
                    ],
                    "overrideHeaderToReplace": [
                        "replacedValue"
                    ],
                    "extraHeaderToReplace": [
                        "shouldBeIgnore"
                    ]
                }
            },
            "path": {
                "regex": "^/(.+)/(.+)$",
                "substitution": "/prefix/$1/infix/$2/postfix"
            },
            "queryStringParameters": {
                "add": {
                    "parameterToAddTwo": [
                        "addedValue"
                    ],
                    "parameterToAddOne": [
                        "addedValue"
                    ]
                },
                "remove": [
                    "overrideParameterToRemove",
                    "requestParameterToRemove"
                ],
                "replace": {
                    "requestParameterToReplace": [
                        "replacedValue"
                    ],
                    "overrideParameterToReplace": [
                        "replacedValue"
                    ],
                    "extraParameterToReplace": [
                        "shouldBeIgnore"
                    ]
                }
            }
        },
        "responseOverride": {
            "body": "some_overridden_body"
        },
        "responseModifier": {
            "cookies": {
                "add": {
                    "cookieToAddOne": "addedValue",
                    "cookieToAddTwo": "addedValue"
                },
                "remove": [
                    "overrideCookieToRemove",
                    "requestCookieToRemove"
                ],
                "replace": {
                    "overrideCookieToReplace": "replacedValue",
                    "requestCookieToReplace": "replacedValue",
                    "extraCookieToReplace": "shouldBeIgnore"
                }
            },
            "headers": {
                "add": {
                    "headerToAddTwo": [
                        "addedValue"
                    ],
                    "headerToAddOne": [
                        "addedValue"
                    ]
                },
                "remove": [
                    "overrideHeaderToRemove",
                    "requestHeaderToRemove"
                ],
                "replace": {
                    "requestHeaderToReplace": [
                        "replacedValue"
                    ],
                    "overrideHeaderToReplace": [
                        "replacedValue"
                    ],
                    "extraHeaderToReplace": [
                        "shouldBeIgnore"
                    ]
                }
            }
        }
    }
}
JSON;

$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_POSTFIELDS     => $json,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json; charset=utf-8'],
    CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
curl_close($ch);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpOverrideForwardedRequest": {
        "requestOverride": {
            "headers": {
                "Host": [
                    "target.host.com"
                ]
            },
            "body": "some_overridden_body"
        },
        "requestModifier": {
            "cookies": {
                "add": {
                    "cookieToAddOne": "addedValue",
                    "cookieToAddTwo": "addedValue"
                },
                "remove": [
                    "overrideCookieToRemove",
                    "requestCookieToRemove"
                ],
                "replace": {
                    "overrideCookieToReplace": "replacedValue",
                    "requestCookieToReplace": "replacedValue",
                    "extraCookieToReplace": "shouldBeIgnore"
                }
            },
            "headers": {
                "add": {
                    "headerToAddTwo": [
                        "addedValue"
                    ],
                    "headerToAddOne": [
                        "addedValue"
                    ]
                },
                "remove": [
                    "overrideHeaderToRemove",
                    "requestHeaderToRemove"
                ],
                "replace": {
                    "requestHeaderToReplace": [
                        "replacedValue"
                    ],
                    "overrideHeaderToReplace": [
                        "replacedValue"
                    ],
                    "extraHeaderToReplace": [
                        "shouldBeIgnore"
                    ]
                }
            },
            "path": {
                "regex": "^/(.+)/(.+)$",
                "substitution": "/prefix/$1/infix/$2/postfix"
            },
            "queryStringParameters": {
                "add": {
                    "parameterToAddTwo": [
                        "addedValue"
                    ],
                    "parameterToAddOne": [
                        "addedValue"
                    ]
                },
                "remove": [
                    "overrideParameterToRemove",
                    "requestParameterToRemove"
                ],
                "replace": {
                    "requestParameterToReplace": [
                        "replacedValue"
                    ],
                    "overrideParameterToReplace": [
                        "replacedValue"
                    ],
                    "extraParameterToReplace": [
                        "shouldBeIgnore"
                    ]
                }
            }
        },
        "responseOverride": {
            "body": "some_overridden_body"
        },
        "responseModifier": {
            "cookies": {
                "add": {
                    "cookieToAddOne": "addedValue",
                    "cookieToAddTwo": "addedValue"
                },
                "remove": [
                    "overrideCookieToRemove",
                    "requestCookieToRemove"
                ],
                "replace": {
                    "overrideCookieToReplace": "replacedValue",
                    "requestCookieToReplace": "replacedValue",
                    "extraCookieToReplace": "shouldBeIgnore"
                }
            },
            "headers": {
                "add": {
                    "headerToAddTwo": [
                        "addedValue"
                    ],
                    "headerToAddOne": [
                        "addedValue"
                    ]
                },
                "remove": [
                    "overrideHeaderToRemove",
                    "requestHeaderToRemove"
                ],
                "replace": {
                    "requestHeaderToReplace": [
                        "replacedValue"
                    ],
                    "overrideHeaderToReplace": [
                        "replacedValue"
                    ],
                    "extraHeaderToReplace": [
                        "shouldBeIgnore"
                    ]
                }
            }
        }
    }
}'

See REST API for full JSON specification

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/some/path")
    )
    .forward(
        forwardOverriddenRequest(
            request()
                .withPath("/some/other/path")
                .withHeader("Host", "any.host.com")
                .withSocketAddress("target.host.com", 1234, SocketAddress.Scheme.HTTPS)
        )
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "path": "/some/path"
    },
    "httpOverrideForwardedRequest": {
        "httpRequest": {
            "path": "/some/other/path",
            "headers": {
                "Host": ["any.host.com"]
            },
            "socketAddress": {
                "host": "target.host.com",
                "port": 1234,
                "scheme": "HTTPS"
            }
        }
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import Expectation

client = MockServerClient("localhost", 1080)
client.upsert(Expectation.from_dict({
    "httpRequest": {
        "path": "/some/path"
    },
    "httpOverrideForwardedRequest": {
        "httpRequest": {
            "path": "/some/other/path",
            "headers": {
                "Host": ["any.host.com"]
            },
            "socketAddress": {
                "host": "target.host.com",
                "port": 1234,
                "scheme": "HTTPS"
            }
        }
    }
}))
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.upsert(MockServer::Expectation.from_hash({
    "httpRequest": {
        "path": "/some/path"
    },
    "httpOverrideForwardedRequest": {
        "httpRequest": {
            "path": "/some/other/path",
            "headers": {
                "Host": ["any.host.com"]
            },
            "socketAddress": {
                "host": "target.host.com",
                "port": 1234,
                "scheme": "HTTPS"
            }
        }
    }
}))
package main

import (
    "bytes"
    "net/http"
)

func main() {
    body := []byte(`{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpOverrideForwardedRequest": {
        "httpRequest": {
            "path": "/some/other/path",
            "headers": {
                "Host": ["any.host.com"]
            },
            "socketAddress": {
                "host": "target.host.com",
                "port": 1234,
                "scheme": "HTTPS"
            }
        }
    }
}`)
    req, _ := http.NewRequest("PUT",
        "http://localhost:1080/mockserver/expectation",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    http.DefaultClient.Do(req)
}
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
    ""httpRequest"": {
        ""path"": ""/some/path""
    },
    ""httpOverrideForwardedRequest"": {
        ""httpRequest"": {
            ""path"": ""/some/other/path"",
            ""headers"": {
                ""Host"": [""any.host.com""]
            },
            ""socketAddress"": {
                ""host"": ""target.host.com"",
                ""port"": 1234,
                ""scheme"": ""HTTPS""
            }
        }
    }
}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpOverrideForwardedRequest": {
        "httpRequest": {
            "path": "/some/other/path",
            "headers": {
                "Host": ["any.host.com"]
            },
            "socketAddress": {
                "host": "target.host.com",
                "port": 1234,
                "scheme": "HTTPS"
            }
        }
    }
}"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
$json = <<<'JSON'
{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpOverrideForwardedRequest": {
        "httpRequest": {
            "path": "/some/other/path",
            "headers": {
                "Host": ["any.host.com"]
            },
            "socketAddress": {
                "host": "target.host.com",
                "port": 1234,
                "scheme": "HTTPS"
            }
        }
    }
}
JSON;

$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_POSTFIELDS     => $json,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json; charset=utf-8'],
    CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
curl_close($ch);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpOverrideForwardedRequest": {
        "httpRequest": {
            "path": "/some/other/path",
            "headers": {
                "Host": ["any.host.com"]
            },
            "socketAddress": {
                "host": "target.host.com",
                "port": 1234,
                "scheme": "HTTPS"
            }
        }
    }
}'

See REST API for full JSON specification

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/some/path")
    )
    .forward(
        forwardOverriddenRequest(
            request()
                .withHeader("Host", "target.host.com")
                .withBody("some_overridden_body")
        ).withDelay(SECONDS, 10)
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "path": "/some/path"
    },
    "httpOverrideForwardedRequest": {
        "httpRequest": {
            "path": "/some/other/path",
            "body": "some_overridden_body",
            "headers": {
                "Host": ["target.host.com"]
            }
        },
        "delay": {
            "timeUnit": "SECONDS",
            "value": 10
        }
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import Expectation

client = MockServerClient("localhost", 1080)
client.upsert(Expectation.from_dict({
    "httpRequest": {
        "path": "/some/path"
    },
    "httpOverrideForwardedRequest": {
        "httpRequest": {
            "path": "/some/other/path",
            "body": "some_overridden_body",
            "headers": {
                "Host": ["target.host.com"]
            }
        },
        "delay": {
            "timeUnit": "SECONDS",
            "value": 10
        }
    }
}))
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.upsert(MockServer::Expectation.from_hash({
    "httpRequest": {
        "path": "/some/path"
    },
    "httpOverrideForwardedRequest": {
        "httpRequest": {
            "path": "/some/other/path",
            "body": "some_overridden_body",
            "headers": {
                "Host": ["target.host.com"]
            }
        },
        "delay": {
            "timeUnit": "SECONDS",
            "value": 10
        }
    }
}))
package main

import (
    "bytes"
    "net/http"
)

func main() {
    body := []byte(`{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpOverrideForwardedRequest": {
        "httpRequest": {
            "path": "/some/other/path",
            "body": "some_overridden_body",
            "headers": {
                "Host": ["target.host.com"]
            }
        },
        "delay": {
            "timeUnit": "SECONDS",
            "value": 10
        }
    }
}`)
    req, _ := http.NewRequest("PUT",
        "http://localhost:1080/mockserver/expectation",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    http.DefaultClient.Do(req)
}
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
    ""httpRequest"": {
        ""path"": ""/some/path""
    },
    ""httpOverrideForwardedRequest"": {
        ""httpRequest"": {
            ""path"": ""/some/other/path"",
            ""body"": ""some_overridden_body"",
            ""headers"": {
                ""Host"": [""target.host.com""]
            }
        },
        ""delay"": {
            ""timeUnit"": ""SECONDS"",
            ""value"": 10
        }
    }
}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpOverrideForwardedRequest": {
        "httpRequest": {
            "path": "/some/other/path",
            "body": "some_overridden_body",
            "headers": {
                "Host": ["target.host.com"]
            }
        },
        "delay": {
            "timeUnit": "SECONDS",
            "value": 10
        }
    }
}"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
$json = <<<'JSON'
{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpOverrideForwardedRequest": {
        "httpRequest": {
            "path": "/some/other/path",
            "body": "some_overridden_body",
            "headers": {
                "Host": ["target.host.com"]
            }
        },
        "delay": {
            "timeUnit": "SECONDS",
            "value": 10
        }
    }
}
JSON;

$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_POSTFIELDS     => $json,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json; charset=utf-8'],
    CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
curl_close($ch);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpOverrideForwardedRequest": {
        "httpRequest": {
            "path": "/some/other/path",
            "body": "some_overridden_body",
            "headers": {
                "Host": ["target.host.com"]
            }
        },
        "delay": {
            "timeUnit": "SECONDS",
            "value": 10
        }
    }
}'

See REST API for full JSON specification

Forward actions support the same distribution-based delays as response actions, allowing realistic latency simulation when proxying requests.

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/some/path")
    )
    .forward(
        forwardOverriddenRequest(
            request()
                .withHeader("Host", "target.host.com")
                .withBody("some_overridden_body")
        ).withDelay(Delay.logNormal(TimeUnit.MILLISECONDS, 200, 800))
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "path": "/some/path"
    },
    "httpOverrideForwardedRequest": {
        "httpRequest": {
            "path": "/some/other/path",
            "body": "some_overridden_body",
            "headers": {
                "Host": ["target.host.com"]
            }
        },
        "delay": {
            "timeUnit": "MILLISECONDS",
            "distribution": {
                "type": "LOG_NORMAL",
                "median": 200,
                "p99": 800
            }
        }
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import Expectation

client = MockServerClient("localhost", 1080)
client.upsert(Expectation.from_dict({
    "httpRequest": {
        "path": "/some/path"
    },
    "httpOverrideForwardedRequest": {
        "httpRequest": {
            "path": "/some/other/path",
            "body": "some_overridden_body",
            "headers": {
                "Host": ["target.host.com"]
            }
        },
        "delay": {
            "timeUnit": "MILLISECONDS",
            "distribution": {
                "type": "LOG_NORMAL",
                "median": 200,
                "p99": 800
            }
        }
    }
}))
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.upsert(MockServer::Expectation.from_hash({
    "httpRequest": {
        "path": "/some/path"
    },
    "httpOverrideForwardedRequest": {
        "httpRequest": {
            "path": "/some/other/path",
            "body": "some_overridden_body",
            "headers": {
                "Host": ["target.host.com"]
            }
        },
        "delay": {
            "timeUnit": "MILLISECONDS",
            "distribution": {
                "type": "LOG_NORMAL",
                "median": 200,
                "p99": 800
            }
        }
    }
}))
package main

import (
    "bytes"
    "net/http"
)

func main() {
    body := []byte(`{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpOverrideForwardedRequest": {
        "httpRequest": {
            "path": "/some/other/path",
            "body": "some_overridden_body",
            "headers": {
                "Host": ["target.host.com"]
            }
        },
        "delay": {
            "timeUnit": "MILLISECONDS",
            "distribution": {
                "type": "LOG_NORMAL",
                "median": 200,
                "p99": 800
            }
        }
    }
}`)
    req, _ := http.NewRequest("PUT",
        "http://localhost:1080/mockserver/expectation",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    http.DefaultClient.Do(req)
}
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
    ""httpRequest"": {
        ""path"": ""/some/path""
    },
    ""httpOverrideForwardedRequest"": {
        ""httpRequest"": {
            ""path"": ""/some/other/path"",
            ""body"": ""some_overridden_body"",
            ""headers"": {
                ""Host"": [""target.host.com""]
            }
        },
        ""delay"": {
            ""timeUnit"": ""MILLISECONDS"",
            ""distribution"": {
                ""type"": ""LOG_NORMAL"",
                ""median"": 200,
                ""p99"": 800
            }
        }
    }
}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpOverrideForwardedRequest": {
        "httpRequest": {
            "path": "/some/other/path",
            "body": "some_overridden_body",
            "headers": {
                "Host": ["target.host.com"]
            }
        },
        "delay": {
            "timeUnit": "MILLISECONDS",
            "distribution": {
                "type": "LOG_NORMAL",
                "median": 200,
                "p99": 800
            }
        }
    }
}"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
$json = <<<'JSON'
{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpOverrideForwardedRequest": {
        "httpRequest": {
            "path": "/some/other/path",
            "body": "some_overridden_body",
            "headers": {
                "Host": ["target.host.com"]
            }
        },
        "delay": {
            "timeUnit": "MILLISECONDS",
            "distribution": {
                "type": "LOG_NORMAL",
                "median": 200,
                "p99": 800
            }
        }
    }
}
JSON;

$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_POSTFIELDS     => $json,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json; charset=utf-8'],
    CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
curl_close($ch);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpOverrideForwardedRequest": {
        "httpRequest": {
            "path": "/some/other/path",
            "body": "some_overridden_body",
            "headers": {
                "Host": ["target.host.com"]
            }
        },
        "delay": {
            "timeUnit": "MILLISECONDS",
            "distribution": {
                "type": "LOG_NORMAL",
                "median": 200,
                "p99": 800
            }
        }
    }
}'

See REST API for full JSON specification

// request.queryStringParameters['userId'] returns an array of values because headers and queryStringParameters have multiple values
String template = "return {\n" +
    "    'path' : \"/somePath\",\n" +
    "    'queryStringParameters' : {\n" +
    "        'userId' : request.queryStringParameters && request.queryStringParameters['userId']\n" +
    "    },\n" +
    "    'headers' : {\n" +
    "        'Host' : [ \"localhost:1081\" ]\n" +
    "    },\n" +
    "    'body': JSON.stringify({'name': 'value'})\n" +
    "};";

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/some/path")
    )
    .forward(
        template(
            HttpTemplate.TemplateType.JAVASCRIPT,
            template
        )
    );
var mockServerClient = require('mockserver-client').mockServerClient;
// request.queryStringParameters['userId'] returns an array of values because headers and queryStringParameters have multiple values
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "path": "/some/path"
    },
    "httpForwardTemplate": {
        "template": "return {\n" +
        "    'path' : \"/somePath\",\n" +
        "    'queryStringParameters' : {\n" +
        "        'userId' : request.queryStringParameters && request.queryStringParameters['userId']\n" +
        "    },\n" +
        "    'headers' : {\n" +
        "        'Host' : [ \"localhost:1081\" ]\n" +
        "    },\n" +
        "    'body': JSON.stringify({'name': 'value'})\n" +
        "};",
        "templateType": "JAVASCRIPT"
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import Expectation

client = MockServerClient("localhost", 1080)
client.upsert(Expectation.from_dict({
    "httpRequest": {
        "path": "/some/path"
    },
    "httpForwardTemplate": {
        "template": "return {\n" +
        "    'path' : \"/somePath\",\n" +
        "    'queryStringParameters' : {\n" +
        "        'userId' : request.queryStringParameters && request.queryStringParameters['userId']\n" +
        "    },\n" +
        "    'headers' : {\n" +
        "        'Host' : [ \"localhost:1081\" ]\n" +
        "    },\n" +
        "    'body': JSON.stringify({'name': 'value'})\n" +
        "};",
        "templateType": "JAVASCRIPT"
    }
}))
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.upsert(MockServer::Expectation.from_hash({
    "httpRequest": {
        "path": "/some/path"
    },
    "httpForwardTemplate": {
        "template": "return {\n" +
        "    'path' : \"/somePath\",\n" +
        "    'queryStringParameters' : {\n" +
        "        'userId' : request.queryStringParameters && request.queryStringParameters['userId']\n" +
        "    },\n" +
        "    'headers' : {\n" +
        "        'Host' : [ \"localhost:1081\" ]\n" +
        "    },\n" +
        "    'body': JSON.stringify({'name': 'value'})\n" +
        "};",
        "templateType": "JAVASCRIPT"
    }
}))
package main

import (
    "bytes"
    "net/http"
)

func main() {
    body := []byte(`{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpForwardTemplate": {
        "template": "return {\n" +
        "    'path' : \"/somePath\",\n" +
        "    'queryStringParameters' : {\n" +
        "        'userId' : request.queryStringParameters && request.queryStringParameters['userId']\n" +
        "    },\n" +
        "    'headers' : {\n" +
        "        'Host' : [ \"localhost:1081\" ]\n" +
        "    },\n" +
        "    'body': JSON.stringify({'name': 'value'})\n" +
        "};",
        "templateType": "JAVASCRIPT"
    }
}`)
    req, _ := http.NewRequest("PUT",
        "http://localhost:1080/mockserver/expectation",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    http.DefaultClient.Do(req)
}
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
    ""httpRequest"": {
        ""path"": ""/some/path""
    },
    ""httpForwardTemplate"": {
        ""template"": ""return {\n"" +
        ""    'path' : \""/somePath\"",\n"" +
        ""    'queryStringParameters' : {\n"" +
        ""        'userId' : request.queryStringParameters && request.queryStringParameters['userId']\n"" +
        ""    },\n"" +
        ""    'headers' : {\n"" +
        ""        'Host' : [ \""localhost:1081\"" ]\n"" +
        ""    },\n"" +
        ""    'body': JSON.stringify({'name': 'value'})\n"" +
        ""};"",
        ""templateType"": ""JAVASCRIPT""
    }
}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpForwardTemplate": {
        "template": "return {\n" +
        "    'path' : \"/somePath\",\n" +
        "    'queryStringParameters' : {\n" +
        "        'userId' : request.queryStringParameters && request.queryStringParameters['userId']\n" +
        "    },\n" +
        "    'headers' : {\n" +
        "        'Host' : [ \"localhost:1081\" ]\n" +
        "    },\n" +
        "    'body': JSON.stringify({'name': 'value'})\n" +
        "};",
        "templateType": "JAVASCRIPT"
    }
}"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
$json = <<<'JSON'
{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpForwardTemplate": {
        "template": "return {\n" +
        "    'path' : \"/somePath\",\n" +
        "    'queryStringParameters' : {\n" +
        "        'userId' : request.queryStringParameters && request.queryStringParameters['userId']\n" +
        "    },\n" +
        "    'headers' : {\n" +
        "        'Host' : [ \"localhost:1081\" ]\n" +
        "    },\n" +
        "    'body': JSON.stringify({'name': 'value'})\n" +
        "};",
        "templateType": "JAVASCRIPT"
    }
}
JSON;

$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_POSTFIELDS     => $json,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json; charset=utf-8'],
    CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
curl_close($ch);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpForwardTemplate": {
        "template": "return {\n" +
        "    'path' : \"/somePath\",\n" +
        "    'queryStringParameters' : {\n" +
        "        'userId' : request.queryStringParameters && request.queryStringParameters['userId']\n" +
        "    },\n" +
        "    'headers' : {\n" +
        "        'Host' : [ \"localhost:1081\" ]\n" +
        "    },\n" +
        "    'body': JSON.stringify({'name': 'value'})\n" +
        "};",
        "templateType": "JAVASCRIPT"
    }
}'

See REST API for full JSON specification

String template = "return {" + System.getProperty("line.separator") +
    "    'path' : request.path.substring(request.path.indexOf('/somePrefix')+'/somePrefix'.length,request.path.length)," + System.getProperty("line.separator") +
    "    'headers' : {" + System.getProperty("line.separator") +
    "        'Host' : [ \"localhost:1081\" ]" + System.getProperty("line.separator") +
    "    }," + System.getProperty("line.separator") +
    "};";

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/somePrefix*")
    )
    .forward(
        template(
            HttpTemplate.TemplateType.JAVASCRIPT,
            template
        )
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "path": "/somePrefix*"
    },
    "httpForwardTemplate": {
        "template": "return {\n" +
        "    'path' : request.path.substring(request.path.indexOf('/somePrefix')+'/somePrefix'.length,request.path.length),\n" +
        "    'headers' : {\n" +
        "        'Host' : [ \"localhost:1081\" ]\n" +
        "    }
        "};",
        "templateType": "JAVASCRIPT"
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import Expectation

client = MockServerClient("localhost", 1080)
client.upsert(Expectation.from_dict({
    "httpRequest": {
        "path": "/somePrefix*"
    },
    "httpForwardTemplate": {
        "template": "return {\n" +
        "    'path' : request.path.substring(request.path.indexOf('/somePrefix')+'/somePrefix'.length,request.path.length),\n" +
        "    'headers' : {\n" +
        "        'Host' : [ \"localhost:1081\" ]\n" +
        "    }\n" +
        "};",
        "templateType": "JAVASCRIPT"
    }
}))
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.upsert(MockServer::Expectation.from_hash({
    "httpRequest": {
        "path": "/somePrefix*"
    },
    "httpForwardTemplate": {
        "template": "return {\n" +
        "    'path' : request.path.substring(request.path.indexOf('/somePrefix')+'/somePrefix'.length,request.path.length),\n" +
        "    'headers' : {\n" +
        "        'Host' : [ \"localhost:1081\" ]\n" +
        "    }\n" +
        "};",
        "templateType": "JAVASCRIPT"
    }
}))
package main

import (
    "bytes"
    "net/http"
)

func main() {
    body := []byte(`{
    "httpRequest": {
        "path": "/somePrefix*"
    },
    "httpForwardTemplate": {
        "template": "return {\n" +
        "    'path' : request.path.substring(request.path.indexOf('/somePrefix')+'/somePrefix'.length,request.path.length),\n" +
        "    'headers' : {\n" +
        "        'Host' : [ \"localhost:1081\" ]\n" +
        "    }\n" +
        "};",
        "templateType": "JAVASCRIPT"
    }
}`)
    req, _ := http.NewRequest("PUT",
        "http://localhost:1080/mockserver/expectation",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    http.DefaultClient.Do(req)
}
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
    ""httpRequest"": {
        ""path"": ""/somePrefix*""
    },
    ""httpForwardTemplate"": {
        ""template"": ""return {\n"" +
        ""    'path' : request.path.substring(request.path.indexOf('/somePrefix')+'/somePrefix'.length,request.path.length),\n"" +
        ""    'headers' : {\n"" +
        ""        'Host' : [ \""localhost:1081\"" ]\n"" +
        ""    }\n"" +
        ""};"",
        ""templateType"": ""JAVASCRIPT""
    }
}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
    "httpRequest": {
        "path": "/somePrefix*"
    },
    "httpForwardTemplate": {
        "template": "return {\n" +
        "    'path' : request.path.substring(request.path.indexOf('/somePrefix')+'/somePrefix'.length,request.path.length),\n" +
        "    'headers' : {\n" +
        "        'Host' : [ \"localhost:1081\" ]\n" +
        "    }\n" +
        "};",
        "templateType": "JAVASCRIPT"
    }
}"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
$json = <<<'JSON'
{
    "httpRequest": {
        "path": "/somePrefix*"
    },
    "httpForwardTemplate": {
        "template": "return {\n" +
        "    'path' : request.path.substring(request.path.indexOf('/somePrefix')+'/somePrefix'.length,request.path.length),\n" +
        "    'headers' : {\n" +
        "        'Host' : [ \"localhost:1081\" ]\n" +
        "    }\n" +
        "};",
        "templateType": "JAVASCRIPT"
    }
}
JSON;

$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_POSTFIELDS     => $json,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json; charset=utf-8'],
    CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
curl_close($ch);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest": {
        "path": "/somePrefix*"
    },
    "httpForwardTemplate": {
        "template": "return {\n" +
        "    'path' : request.path.substring(request.path.indexOf('/somePrefix')+'/somePrefix'.length,request.path.length),\n" +
        "    'headers' : {\n" +
        "        'Host' : [ \"localhost:1081\" ]\n" +
        "    }\n" +
        "};",
        "templateType": "JAVASCRIPT"
    }
}'

See REST API for full JSON specification

// request.cookies['SessionId'] returns a single value because cookies only contain a single value
String template = "return {\n" +
    "    'path' : \"/somePath\",\n" +
    "    'cookies' : {\n" +
    "        'SessionId' : request.cookies && request.cookies['SessionId']\n" +
    "    },\n" +
    "    'headers' : {\n" +
    "        'Host' : [ \"localhost:1081\" ]\n" +
    "    },\n" +
    "    'keepAlive' : true,\n" +
    "    'secure' : true,\n" +
    "    'body' : \"some_body\"\n" +
    "};";

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/some/path")
    )
    .forward(
        template(HttpTemplate.TemplateType.JAVASCRIPT)
            .withTemplate(template)
            .withDelay(TimeUnit.SECONDS, 20)
    );
var mockServerClient = require('mockserver-client').mockServerClient;
// request.cookies['SessionId'] returns a single value because cookies only contain a single value
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "path": "/some/path"
    },
    "httpForwardTemplate": {
        "template": "return {\n" +
        "    'path' : \"/somePath\",\n" +
        "    'cookies' : {\n" +
        "        'SessionId' : request.cookies && request.cookies['SessionId']\n" +
        "    },\n" +
        "    'headers' : {\n" +
        "        'Host' : [ \"localhost:1081\" ]\n" +
        "    },\n" +
        "    'keepAlive' : true,\n" +
        "    'secure' : true,\n" +
        "    'body' : \"some_body\"\n" +
        "};",
        "templateType": "JAVASCRIPT",
        "delay": {"timeUnit": "SECONDS", "value": 20}
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import Expectation

client = MockServerClient("localhost", 1080)
client.upsert(Expectation.from_dict({
    "httpRequest": {
        "path": "/some/path"
    },
    "httpForwardTemplate": {
        "template": "return {\n" +
        "    'path' : \"/somePath\",\n" +
        "    'cookies' : {\n" +
        "        'SessionId' : request.cookies && request.cookies['SessionId']\n" +
        "    },\n" +
        "    'headers' : {\n" +
        "        'Host' : [ \"localhost:1081\" ]\n" +
        "    },\n" +
        "    'keepAlive' : True,\n" +
        "    'secure' : True,\n" +
        "    'body' : \"some_body\"\n" +
        "};",
        "templateType": "JAVASCRIPT",
        "delay": {"timeUnit": "SECONDS", "value": 20}
    }
}))
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.upsert(MockServer::Expectation.from_hash({
    "httpRequest": {
        "path": "/some/path"
    },
    "httpForwardTemplate": {
        "template": "return {\n" +
        "    'path' : \"/somePath\",\n" +
        "    'cookies' : {\n" +
        "        'SessionId' : request.cookies && request.cookies['SessionId']\n" +
        "    },\n" +
        "    'headers' : {\n" +
        "        'Host' : [ \"localhost:1081\" ]\n" +
        "    },\n" +
        "    'keepAlive' : true,\n" +
        "    'secure' : true,\n" +
        "    'body' : \"some_body\"\n" +
        "};",
        "templateType": "JAVASCRIPT",
        "delay": {"timeUnit": "SECONDS", "value": 20}
    }
}))
package main

import (
    "bytes"
    "net/http"
)

func main() {
    body := []byte(`{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpForwardTemplate": {
        "template": "return {\n" +
        "    'path' : \"/somePath\",\n" +
        "    'cookies' : {\n" +
        "        'SessionId' : request.cookies && request.cookies['SessionId']\n" +
        "    },\n" +
        "    'headers' : {\n" +
        "        'Host' : [ \"localhost:1081\" ]\n" +
        "    },\n" +
        "    'keepAlive' : true,\n" +
        "    'secure' : true,\n" +
        "    'body' : \"some_body\"\n" +
        "};",
        "templateType": "JAVASCRIPT",
        "delay": {"timeUnit": "SECONDS", "value": 20}
    }
}`)
    req, _ := http.NewRequest("PUT",
        "http://localhost:1080/mockserver/expectation",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    http.DefaultClient.Do(req)
}
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
    ""httpRequest"": {
        ""path"": ""/some/path""
    },
    ""httpForwardTemplate"": {
        ""template"": ""return {\n"" +
        ""    'path' : \""/somePath\"",\n"" +
        ""    'cookies' : {\n"" +
        ""        'SessionId' : request.cookies && request.cookies['SessionId']\n"" +
        ""    },\n"" +
        ""    'headers' : {\n"" +
        ""        'Host' : [ \""localhost:1081\"" ]\n"" +
        ""    },\n"" +
        ""    'keepAlive' : true,\n"" +
        ""    'secure' : true,\n"" +
        ""    'body' : \""some_body\""\n"" +
        ""};"",
        ""templateType"": ""JAVASCRIPT"",
        ""delay"": {""timeUnit"": ""SECONDS"", ""value"": 20}
    }
}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpForwardTemplate": {
        "template": "return {\n" +
        "    'path' : \"/somePath\",\n" +
        "    'cookies' : {\n" +
        "        'SessionId' : request.cookies && request.cookies['SessionId']\n" +
        "    },\n" +
        "    'headers' : {\n" +
        "        'Host' : [ \"localhost:1081\" ]\n" +
        "    },\n" +
        "    'keepAlive' : true,\n" +
        "    'secure' : true,\n" +
        "    'body' : \"some_body\"\n" +
        "};",
        "templateType": "JAVASCRIPT",
        "delay": {"timeUnit": "SECONDS", "value": 20}
    }
}"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
$json = <<<'JSON'
{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpForwardTemplate": {
        "template": "return {\n" +
        "    'path' : \"/somePath\",\n" +
        "    'cookies' : {\n" +
        "        'SessionId' : request.cookies && request.cookies['SessionId']\n" +
        "    },\n" +
        "    'headers' : {\n" +
        "        'Host' : [ \"localhost:1081\" ]\n" +
        "    },\n" +
        "    'keepAlive' : true,\n" +
        "    'secure' : true,\n" +
        "    'body' : \"some_body\"\n" +
        "};",
        "templateType": "JAVASCRIPT",
        "delay": {"timeUnit": "SECONDS", "value": 20}
    }
}
JSON;

$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_POSTFIELDS     => $json,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json; charset=utf-8'],
    CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
curl_close($ch);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpForwardTemplate": {
        "template": "return {\n" +
        "    'path' : \"/somePath\",\n" +
        "    'cookies' : {\n" +
        "        'SessionId' : request.cookies && request.cookies['SessionId']\n" +
        "    },\n" +
        "    'headers' : {\n" +
        "        'Host' : [ \"localhost:1081\" ]\n" +
        "    },\n" +
        "    'keepAlive' : true,\n" +
        "    'secure' : true,\n" +
        "    'body' : \"some_body\"\n" +
        "};",
        "templateType": "JAVASCRIPT",
        "delay": {"timeUnit": "SECONDS", "value": 20}
    }
}'

See REST API for full JSON specification

// $!request.queryStringParameters['userId'] returns an array of values because headers and queryStringParameters have multiple values
String template = "{\n" +
    "    'path' : \"/somePath\",\n" +
    "    'queryStringParameters' : {\n" +
    "        'userId' : [ \"$!request.queryStringParameters['userId'][0]\" ]\n" +
    "    },\n" +
    "    'cookies' : {\n" +
    "        'SessionId' : \"$!request.cookies['SessionId']\"\n" +
    "    },\n" +
    "    'headers' : {\n" +
    "        'Host' : [ \"localhost:1081\" ]\n" +
    "    },\n" +
    "    'body': \"{'name': 'value'}\"\n" +
    "}";

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/some/path")
    )
    .forward(
        template(
            HttpTemplate.TemplateType.VELOCITY,
            template
        )
    );
var mockServerClient = require('mockserver-client').mockServerClient;
// $!request.queryStringParameters['userId'] returns an array of values because headers and queryStringParameters have multiple values
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "path": "/some/path"
    },
    "httpForwardTemplate": {
        "template": "{\n" +
        "    'path' : \"/somePath\",\n" +
        "    'queryStringParameters' : {\n" +
        "        'userId' : [ \"$!request.queryStringParameters['userId'][0]\" ]\n" +
        "    },\n" +
        "    'cookies' : {\n" +
        "        'SessionId' : \"$!request.cookies['SessionId']\"\n" +
        "    },\n" +
        "    'headers' : {\n" +
        "        'Host' : [ \"localhost:1081\" ]\n" +
        "    },\n" +
        "    'body': \"{'name': 'value'}\"\n" +
        "}",
        "templateType": "VELOCITY"
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import Expectation

client = MockServerClient("localhost", 1080)
client.upsert(Expectation.from_dict({
    "httpRequest": {
        "path": "/some/path"
    },
    "httpForwardTemplate": {
        "template": "{\n" +
        "    'path' : \"/somePath\",\n" +
        "    'queryStringParameters' : {\n" +
        "        'userId' : [ \"$!request.queryStringParameters['userId'][0]\" ]\n" +
        "    },\n" +
        "    'cookies' : {\n" +
        "        'SessionId' : \"$!request.cookies['SessionId']\"\n" +
        "    },\n" +
        "    'headers' : {\n" +
        "        'Host' : [ \"localhost:1081\" ]\n" +
        "    },\n" +
        "    'body': \"{'name': 'value'}\"\n" +
        "}",
        "templateType": "VELOCITY"
    }
}))
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.upsert(MockServer::Expectation.from_hash({
    "httpRequest": {
        "path": "/some/path"
    },
    "httpForwardTemplate": {
        "template": "{\n" +
        "    'path' : \"/somePath\",\n" +
        "    'queryStringParameters' : {\n" +
        "        'userId' : [ \"$!request.queryStringParameters['userId'][0]\" ]\n" +
        "    },\n" +
        "    'cookies' : {\n" +
        "        'SessionId' : \"$!request.cookies['SessionId']\"\n" +
        "    },\n" +
        "    'headers' : {\n" +
        "        'Host' : [ \"localhost:1081\" ]\n" +
        "    },\n" +
        "    'body': \"{'name': 'value'}\"\n" +
        "}",
        "templateType": "VELOCITY"
    }
}))
package main

import (
    "bytes"
    "net/http"
)

func main() {
    body := []byte(`{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpForwardTemplate": {
        "template": "{\n" +
        "    'path' : \"/somePath\",\n" +
        "    'queryStringParameters' : {\n" +
        "        'userId' : [ \"$!request.queryStringParameters['userId'][0]\" ]\n" +
        "    },\n" +
        "    'cookies' : {\n" +
        "        'SessionId' : \"$!request.cookies['SessionId']\"\n" +
        "    },\n" +
        "    'headers' : {\n" +
        "        'Host' : [ \"localhost:1081\" ]\n" +
        "    },\n" +
        "    'body': \"{'name': 'value'}\"\n" +
        "}",
        "templateType": "VELOCITY"
    }
}`)
    req, _ := http.NewRequest("PUT",
        "http://localhost:1080/mockserver/expectation",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    http.DefaultClient.Do(req)
}
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
    ""httpRequest"": {
        ""path"": ""/some/path""
    },
    ""httpForwardTemplate"": {
        ""template"": ""{\n"" +
        ""    'path' : \""/somePath\"",\n"" +
        ""    'queryStringParameters' : {\n"" +
        ""        'userId' : [ \""$!request.queryStringParameters['userId'][0]\"" ]\n"" +
        ""    },\n"" +
        ""    'cookies' : {\n"" +
        ""        'SessionId' : \""$!request.cookies['SessionId']\""\n"" +
        ""    },\n"" +
        ""    'headers' : {\n"" +
        ""        'Host' : [ \""localhost:1081\"" ]\n"" +
        ""    },\n"" +
        ""    'body': \""{'name': 'value'}\""\n"" +
        ""}"",
        ""templateType"": ""VELOCITY""
    }
}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpForwardTemplate": {
        "template": "{\n" +
        "    'path' : \"/somePath\",\n" +
        "    'queryStringParameters' : {\n" +
        "        'userId' : [ \"$!request.queryStringParameters['userId'][0]\" ]\n" +
        "    },\n" +
        "    'cookies' : {\n" +
        "        'SessionId' : \"$!request.cookies['SessionId']\"\n" +
        "    },\n" +
        "    'headers' : {\n" +
        "        'Host' : [ \"localhost:1081\" ]\n" +
        "    },\n" +
        "    'body': \"{'name': 'value'}\"\n" +
        "}",
        "templateType": "VELOCITY"
    }
}"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
$json = <<<'JSON'
{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpForwardTemplate": {
        "template": "{\n" +
        "    'path' : \"/somePath\",\n" +
        "    'queryStringParameters' : {\n" +
        "        'userId' : [ \"$!request.queryStringParameters['userId'][0]\" ]\n" +
        "    },\n" +
        "    'cookies' : {\n" +
        "        'SessionId' : \"$!request.cookies['SessionId']\"\n" +
        "    },\n" +
        "    'headers' : {\n" +
        "        'Host' : [ \"localhost:1081\" ]\n" +
        "    },\n" +
        "    'body': \"{'name': 'value'}\"\n" +
        "}",
        "templateType": "VELOCITY"
    }
}
JSON;

$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_POSTFIELDS     => $json,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json; charset=utf-8'],
    CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
curl_close($ch);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpForwardTemplate": {
        "template": "{\n" +
        "    'path' : \"/somePath\",\n" +
        "    'queryStringParameters' : {\n" +
        "        'userId' : [ \"$!request.queryStringParameters['userId'][0]\" ]\n" +
        "    },\n" +
        "    'cookies' : {\n" +
        "        'SessionId' : \"$!request.cookies['SessionId']\"\n" +
        "    },\n" +
        "    'headers' : {\n" +
        "        'Host' : [ \"localhost:1081\" ]\n" +
        "    },\n" +
        "    'body': \"{'name': 'value'}\"\n" +
        "}",
        "templateType": "VELOCITY"
    }
}'

See REST API for full JSON specification

A response template allows you to transform the response returned from the upstream server using a template that has access to both the original request and the upstream response. This is useful when you need to dynamically modify responses based on request context — for example, injecting request headers into the response body or conditionally changing the status code.

The template receives two objects: request (the original request) and response (the upstream response). The template must return a valid HTTP response JSON object.

from mockserver.client import MockServerClient
from mockserver.models import Expectation

client = MockServerClient("localhost", 1080)
client.upsert(Expectation.from_dict({
    "httpRequest": {
        "path": "/some/path"
    },
    "httpOverrideForwardedRequest": {
        "requestOverride": {
            "headers": {
                "Host": ["target.host.com"]
            }
        },
        "responseTemplate": {
            "templateType": "JAVASCRIPT",
            "template": "return { 'statusCode': response.statusCode, 'headers': response.headers, 'body': JSON.stringify({ 'originalBody': response.body, 'requestPath': request.path }) };"
        }
    }
}))
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.upsert(MockServer::Expectation.from_hash({
    "httpRequest": {
        "path": "/some/path"
    },
    "httpOverrideForwardedRequest": {
        "requestOverride": {
            "headers": {
                "Host": ["target.host.com"]
            }
        },
        "responseTemplate": {
            "templateType": "JAVASCRIPT",
            "template": "return { 'statusCode': response.statusCode, 'headers': response.headers, 'body': JSON.stringify({ 'originalBody': response.body, 'requestPath': request.path }) };"
        }
    }
}))
package main

import (
    "bytes"
    "net/http"
)

func main() {
    body := []byte(`{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpOverrideForwardedRequest": {
        "requestOverride": {
            "headers": {
                "Host": ["target.host.com"]
            }
        },
        "responseTemplate": {
            "templateType": "JAVASCRIPT",
            "template": "return { 'statusCode': response.statusCode, 'headers': response.headers, 'body': JSON.stringify({ 'originalBody': response.body, 'requestPath': request.path }) };"
        }
    }
}`)
    req, _ := http.NewRequest("PUT",
        "http://localhost:1080/mockserver/expectation",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    http.DefaultClient.Do(req)
}
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
    ""httpRequest"": {
        ""path"": ""/some/path""
    },
    ""httpOverrideForwardedRequest"": {
        ""requestOverride"": {
            ""headers"": {
                ""Host"": [""target.host.com""]
            }
        },
        ""responseTemplate"": {
            ""templateType"": ""JAVASCRIPT"",
            ""template"": ""return { 'statusCode': response.statusCode, 'headers': response.headers, 'body': JSON.stringify({ 'originalBody': response.body, 'requestPath': request.path }) };""
        }
    }
}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpOverrideForwardedRequest": {
        "requestOverride": {
            "headers": {
                "Host": ["target.host.com"]
            }
        },
        "responseTemplate": {
            "templateType": "JAVASCRIPT",
            "template": "return { 'statusCode': response.statusCode, 'headers': response.headers, 'body': JSON.stringify({ 'originalBody': response.body, 'requestPath': request.path }) };"
        }
    }
}"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
$json = <<<'JSON'
{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpOverrideForwardedRequest": {
        "requestOverride": {
            "headers": {
                "Host": ["target.host.com"]
            }
        },
        "responseTemplate": {
            "templateType": "JAVASCRIPT",
            "template": "return { 'statusCode': response.statusCode, 'headers': response.headers, 'body': JSON.stringify({ 'originalBody': response.body, 'requestPath': request.path }) };"
        }
    }
}
JSON;

$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_POSTFIELDS     => $json,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json; charset=utf-8'],
    CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
curl_close($ch);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpOverrideForwardedRequest": {
        "requestOverride": {
            "headers": {
                "Host": ["target.host.com"]
            }
        },
        "responseTemplate": {
            "templateType": "JAVASCRIPT",
            "template": "return { 'statusCode': response.statusCode, 'headers': response.headers, 'body': JSON.stringify({ 'originalBody': response.body, 'requestPath': request.path }) };"
        }
    }
}'

See REST API for full JSON specification

When using a templated forward (JavaScript, Velocity, or Mustache), you can also specify a responseOverride and/or responseModifier to statically modify the response returned from the upstream server — without needing a separate response template.

from mockserver.client import MockServerClient
from mockserver.models import Expectation

client = MockServerClient("localhost", 1080)
client.upsert(Expectation.from_dict({
    "httpRequest": {
        "path": "/some/path"
    },
    "httpForwardTemplate": {
        "templateType": "JAVASCRIPT",
        "template": "return { 'path': '/target' + request.path, 'headers': { 'Host': ['target.host.com'] } };",
        "responseOverride": {
            "headers": {
                "x-proxy": ["mockserver"]
            }
        }
    }
}))
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.upsert(MockServer::Expectation.from_hash({
    "httpRequest": {
        "path": "/some/path"
    },
    "httpForwardTemplate": {
        "templateType": "JAVASCRIPT",
        "template": "return { 'path': '/target' + request.path, 'headers': { 'Host': ['target.host.com'] } };",
        "responseOverride": {
            "headers": {
                "x-proxy": ["mockserver"]
            }
        }
    }
}))
package main

import (
    "bytes"
    "net/http"
)

func main() {
    body := []byte(`{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpForwardTemplate": {
        "templateType": "JAVASCRIPT",
        "template": "return { 'path': '/target' + request.path, 'headers': { 'Host': ['target.host.com'] } };",
        "responseOverride": {
            "headers": {
                "x-proxy": ["mockserver"]
            }
        }
    }
}`)
    req, _ := http.NewRequest("PUT",
        "http://localhost:1080/mockserver/expectation",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    http.DefaultClient.Do(req)
}
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
    ""httpRequest"": {
        ""path"": ""/some/path""
    },
    ""httpForwardTemplate"": {
        ""templateType"": ""JAVASCRIPT"",
        ""template"": ""return { 'path': '/target' + request.path, 'headers': { 'Host': ['target.host.com'] } };"",
        ""responseOverride"": {
            ""headers"": {
                ""x-proxy"": [""mockserver""]
            }
        }
    }
}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpForwardTemplate": {
        "templateType": "JAVASCRIPT",
        "template": "return { 'path': '/target' + request.path, 'headers': { 'Host': ['target.host.com'] } };",
        "responseOverride": {
            "headers": {
                "x-proxy": ["mockserver"]
            }
        }
    }
}"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
$json = <<<'JSON'
{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpForwardTemplate": {
        "templateType": "JAVASCRIPT",
        "template": "return { 'path': '/target' + request.path, 'headers': { 'Host': ['target.host.com'] } };",
        "responseOverride": {
            "headers": {
                "x-proxy": ["mockserver"]
            }
        }
    }
}
JSON;

$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_POSTFIELDS     => $json,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json; charset=utf-8'],
    CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
curl_close($ch);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpForwardTemplate": {
        "templateType": "JAVASCRIPT",
        "template": "return { 'path': '/target' + request.path, 'headers': { 'Host': ['target.host.com'] } };",
        "responseOverride": {
            "headers": {
                "x-proxy": ["mockserver"]
            }
        }
    }
}'

See REST API for full JSON specification

public class CallbackActionExamples {

    public void forwardClassCallback() {
        new ClientAndServer(1080)
            .when(
                request()
                    .withPath("/some.*")
            )
            .forward(
                callback()
                    .withCallbackClass(TestExpectationForwardCallback.class)
            );
    }

    public static class TestExpectationForwardCallback implements ExpectationForwardCallback {

        @Override
        public HttpRequest handle(HttpRequest httpRequest) {
            return request()
                .withPath(httpRequest.getPath())
                .withMethod("POST")
                .withHeaders(
                    header("x-callback", "test_callback_header"),
                    header("Content-Length", "a_callback_request".getBytes(UTF_8).length),
                    header("Connection", "keep-alive")
                )
                .withBody("a_callback_request");
        }
    }

}
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "path": "/some.*"
    },
    "httpForwardClassCallback": {
        "callbackClass": "org.mockserver.examples.mockserver.CallbackActionExamples$TestExpectationForwardCallback"
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);
$json = <<<'JSON'
{
    "httpRequest" : {
        "path" : "/some.*"
    },
    "httpForwardClassCallback" : {
        "callbackClass" : "org.mockserver.examples.mockserver.CallbackActionExamples$TestExpectationForwardCallback"
    }
}
JSON;

$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_POSTFIELDS     => $json,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json; charset=utf-8'],
    CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
curl_close($ch);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest" : {
        "path" : "/some.*"
    },
    "httpForwardClassCallback" : {
        "callbackClass" : "org.mockserver.examples.mockserver.CallbackActionExamples$TestExpectationForwardCallback"
    }
}'

To use a class callback MockServer must be able to load the class from the classpath.

The callback class must:

  • implement
    • org.mockserver.mock.action.ExpectationForwardCallback to dynamically override the request or
    • org.mockserver.mock.action.ExpectationForwardAndResponseCallback to dynamically override the request and the response
  • have a zero argument constructor
  • be available in the classpath of the MockServer

If MockServer is started using the JUnit 4 @Rule, the JUnit 5 Test Extension, ClientAndServer or directly using org.mockserver.netty.MockServer then any class present in the main or test classpaths will be visible to MockServer.

If MockServer is started using the maven plugin only the non-forked goals (such as runAndWait and start) will be able to load classes from the main and test classpaths. It is possible to use classes from a separate maven dependency, however, this dependency must be specified in the plugin configuration dependencies section. Any dependency added to the plugin configuration dependencies section will then be visible to MockServer run using both forked and non-forked goals.

The following configuration shows how to use classes from a separate maven dependency in callback actions.

 <plugin>
     <groupId>org.mock-server</groupId>
     <artifactId>mockserver-maven-plugin</artifactId>
     <version>7.2.0</version>
     <configuration>
        <serverPort>1080</serverPort>
        <logLevel>DEBUG</logLevel>
        <pipeLogToConsole>true</pipeLogToConsole>
     </configuration>
     <executions>
         <execution>
             <id>pre-integration-test</id>
             <phase>pre-integration-test</phase>
             <goals>
                 <goal>runForked</goal>
             </goals>
         </execution>
         <execution>
             <id>post-integration-test</id>
             <phase>post-integration-test</phase>
             <goals>
                 <goal>stopForked</goal>
             </goals>
         </execution>
     </executions>
     <dependencies>
         <dependency>
             <groupId>com.my-domain</groupId>
             <artifactId>my-callback-dependency</artifactId>
             <version>1.0.0</version>
         </dependency>
     </dependencies>
 </plugin>

If MockServer is started using the command line then the callback classes must be added to the JVM using the classpath command line switch (cp or classpath). The classpath switch is ignored by the JVM if the jar switch is used. So to run the MockServer from the command line directly (with mockserver-netty-7.2.0-no-dependencies.jar) you must specify the org.mockserver.cli.Main main class specifically and not use the jar switch as follows.

java -Dfile.encoding=UTF-8 -cp mockserver-netty-7.2.0-no-dependencies.jar:my-callback-dependency.jar org.mockserver.cli.Main -serverPort 1080
new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/some/path")
    )
    .forward(
        new ExpectationForwardCallback() {
            @Override
            public HttpRequest handle(HttpRequest httpRequest) {
                return request()
                    .withPath(httpRequest.getPath())
                    .withMethod("POST")
                    .withHeaders(
                        header("x-callback", "test_callback_header"),
                        header("Content-Length", "a_callback_request".getBytes(UTF_8).length),
                        header("Connection", "keep-alive")
                    )
                    .withBody("a_callback_request");
            }
        }
    );
new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/some/path")
    )
    .forward(
        httpRequest -> request()
                    .withPath(httpRequest.getPath())
                    .withMethod("POST")
                    .withHeaders(
                        header("x-callback", "test_callback_header"),
                        header("Content-Length", "a_callback_request".getBytes(UTF_8).length),
                        header("Connection", "keep-alive")
                    )
                    .withBody("a_callback_request")
    );

When using org.mockserver.client.MockServerClient each method / closure callback has a separate web socket client. To ensure the number of total threads does not grow too large for large numbers of method / closure callback expectations the default event loop thread pool for the web socket client is kept fairly low. However, if an extremely large load is matched against a single method / closure callback expectation the event loop thread pool may not be large enough for its web socket client.

The number of threads for the event loop thread pool for each web socket client (i.e. for each expectation with a method / closure callback) can be configured and is described in the configuration section.

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/some/path")
    )
    .forward(
        new ExpectationForwardCallback() {
            @Override
            public HttpRequest handle(HttpRequest httpRequest) throws Exception {
                return request()
                    .withPath(httpRequest.getPath())
                    .withMethod("POST")
                    .withHeaders(
                        header("x-callback", "test_callback_header"),
                        header("Content-Length", "a_callback_request".getBytes(UTF_8).length),
                        header("Connection", "keep-alive")
                    )
                    .withBody("a_callback_request");
            }
        },
        new ExpectationForwardAndResponseCallback() {
            @Override
            public HttpResponse handle(HttpRequest httpRequest, HttpResponse httpResponse) throws Exception {
                return httpResponse
                    .withHeader("x-response-test", "x-response-test")
                    .removeHeader(CONTENT_LENGTH.toString())
                    .withBody("some_overridden_response_body");
            }
        }
    );
new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/some/path")
    )
    .forward(
        httpRequest ->
            request()
                .withPath(httpRequest.getPath())
                .withMethod("POST")
                .withHeaders(
                    header("x-callback", "test_callback_header"),
                    header("Content-Length", "a_callback_request".getBytes(UTF_8).length),
                    header("Connection", "keep-alive")
                )
                .withBody("a_callback_request"),
        (httpRequest, httpResponse) ->
            httpResponse
                .withHeader("x-response-test", "x-response-test")
                .removeHeader(CONTENT_LENGTH.toString())
                .withBody("some_overridden_response_body")
    );

When using org.mockserver.client.MockServerClient each method / closure callback has a separate web socket client. To ensure the number of total threads does not grow too large for large numbers of method / closure callback expectations the default event loop thread pool for the web socket client is kept fairly low. However, if an extremely large load is matched against a single method / closure callback expectation the event loop thread pool may not be large enough for its web socket client.

The number of threads for the event loop thread pool for each web socket client (i.e. for each expectation with a method / closure callback) can be configured and is described in the configuration section.

 

Forward with Fallback

A forward with fallback action (httpForwardWithFallback) forwards the request to an upstream service, but returns a pre-configured fallback response when the upstream returns an error status code or the connection fails. This is unique to MockServer's hybrid mock+proxy architecture.

Use cases:

  • Resilience testing - test your application's behaviour when a downstream service is flaky
  • Development against partially-available services - work offline with cached/mock responses while still connecting to real services when they are available
  • Circuit breaker simulation - provide a fallback response on specific status codes like 429 (rate limited) or 503 (service unavailable)

Configuration

  • httpForward - the upstream target (host, port, scheme)
  • fallbackResponse - the mock response to return when fallback is triggered
  • fallbackOnStatusCodes - list of HTTP status codes that trigger the fallback (defaults to 500-599 when not specified)
  • fallbackOnTimeout - whether to return the fallback on connection errors or timeouts (defaults to true)

Java Client Example

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/api/downstream")
    )
    .forwardWithFallback(
        forwardWithFallback()
            .withForward(
                forward()
                    .withHost("downstream-service.example.com")
                    .withPort(443)
                    .withScheme(HttpForward.Scheme.HTTPS)
            )
            .withFallback(
                response()
                    .withStatusCode(200)
                    .withBody("{\"status\": \"cached\", \"data\": []}")
            )
            .withFallbackOnStatusCodes(500, 502, 503, 504)
            .withFallbackOnTimeout(true)
    );

JSON Example

{
    "httpRequest": {
        "path": "/api/downstream"
    },
    "httpForwardWithFallback": {
        "httpForward": {
            "host": "downstream-service.example.com",
            "port": 443,
            "scheme": "HTTPS"
        },
        "fallbackResponse": {
            "statusCode": 200,
            "body": "{\"status\": \"cached\", \"data\": []}"
        },
        "fallbackOnStatusCodes": [500, 502, 503, 504],
        "fallbackOnTimeout": true
    }
}
 

An error action can return an invalid response as a sequence of bytes or drop the connection (with an optional delay)

The following code examples show how to create different error actions.

An error action can include a delay to simulate a service that hangs before dropping the connection, which is useful for testing timeout handling.

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/some/path")
    )
    .error(
        error()
            .withDropConnection(true)
            .withDelay(TimeUnit.SECONDS, 5)
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "path": "/some/path"
    },
    "httpError": {
        "dropConnection": true,
        "delay": {
            "timeUnit": "SECONDS",
            "value": 5
        }
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import HttpError, HttpRequest, Delay

client = MockServerClient("localhost", 1080)
client.when(
    HttpRequest.request("/some/path")
).error(
    HttpError(drop_connection=True, delay=Delay(time_unit="SECONDS", value=5))
)
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.when(
    MockServer::HttpRequest.new(path: '/some/path')
).error(
    MockServer::HttpError.new(
        drop_connection: true,
        delay: MockServer::Delay.new(time_unit: 'SECONDS', value: 5)
    )
)
import mockserver "github.com/mock-server/mockserver-monorepo/mockserver-client-go"

client := mockserver.New("localhost", 1080)
client.When(
    mockserver.Request().Path("/some/path"),
).RespondWithError(
    mockserver.Error().DropConnection(true).WithDelay("SECONDS", 5),
)
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
    ""httpRequest"": {
        ""path"": ""/some/path""
    },
    ""httpError"": {
        ""dropConnection"": true,
        ""delay"": {
            ""timeUnit"": ""SECONDS"",
            ""value"": 5
        }
    }
}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpError": {
        "dropConnection": true,
        "delay": {
            "timeUnit": "SECONDS",
            "value": 5
        }
    }
}"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
$json = <<<'JSON'
{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpError": {
        "dropConnection": true,
        "delay": {
            "timeUnit": "SECONDS",
            "value": 5
        }
    }
}
JSON;

$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_POSTFIELDS     => $json,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json; charset=utf-8'],
    CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
curl_close($ch);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpError": {
        "dropConnection": true,
        "delay": {
            "timeUnit": "SECONDS",
            "value": 5
        }
    }
}'

See REST API for full JSON specification

// generate random bytes
byte[] randomByteArray = new byte[25];
new Random().nextBytes(randomByteArray);

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/some/path")
    )
    .error(
        error()
            .withDropConnection(true)
            .withResponseBytes(randomByteArray)
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest": {
        "path": "/some/path"
    },
    "httpError": {
        "dropConnection": true,
        "responseBytes": "eQqmdjEEoaXnCvcK6lOAIZeU+Pn+womxmg=="
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import HttpError, HttpRequest

client = MockServerClient("localhost", 1080)
client.when(
    HttpRequest.request("/some/path")
).error(
    HttpError(drop_connection=True, response_bytes="eQqmdjEEoaXnCvcK6lOAIZeU+Pn+womxmg==")
)
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.when(
    MockServer::HttpRequest.new(path: '/some/path')
).error(
    MockServer::HttpError.new(
        drop_connection: true,
        response_bytes: 'eQqmdjEEoaXnCvcK6lOAIZeU+Pn+womxmg=='
    )
)
import mockserver "github.com/mock-server/mockserver-monorepo/mockserver-client-go"

client := mockserver.New("localhost", 1080)
client.When(
    mockserver.Request().Path("/some/path"),
).RespondWithError(
    mockserver.Error().DropConnection(true).ResponseBytes("eQqmdjEEoaXnCvcK6lOAIZeU+Pn+womxmg=="),
)
using MockServer.Client;
using MockServer.Client.Models;

using var client = new MockServerClient("localhost", 1080);
client.When(
    HttpRequest.Request().WithPath("/some/path")
).Error(
    HttpError.Error()
        .WithDropConnection(true)
        .WithResponseBytes("eQqmdjEEoaXnCvcK6lOAIZeU+Pn+womxmg==")
);
use mockserver_client::{ClientBuilder, HttpRequest, HttpError};

let client = ClientBuilder::new("localhost", 1080).build().unwrap();
client.when(HttpRequest::new().path("/some/path"))
    .error(
        HttpError::new()
            .drop_connection(true)
            .response_bytes("eQqmdjEEoaXnCvcK6lOAIZeU+Pn+womxmg==")
    )
    .unwrap();
use MockServer\MockServerClient;
use MockServer\HttpRequest;
use MockServer\HttpError;

$client = new MockServerClient('localhost', 1080);
$client->when(
    HttpRequest::request()
        ->path('/some/path')
)->error(
    HttpError::error()
        ->dropConnection(true)
        ->responseBytes('eQqmdjEEoaXnCvcK6lOAIZeU+Pn+womxmg==')
);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest": {
        "path": "/some/path"
    },
    "httpError": {
        "dropConnection": true,
        "responseBytes": "eQqmdjEEoaXnCvcK6lOAIZeU+Pn+womxmg=="
    }
}'

See REST API for full JSON specification

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/some/path")
    )
    .error(
        error()
            .withDropConnection(true)
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).mockAnyResponse({
    "httpRequest" : {
        "path" : "/some/path"
    },
    "httpError" : {
        "dropConnection" : true
    }
}).then(
    function () {
        console.log("expectation created");
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

from mockserver.client import MockServerClient
from mockserver.models import HttpError, HttpRequest

client = MockServerClient("localhost", 1080)
client.when(
    HttpRequest.request("/some/path")
).error(
    HttpError(drop_connection=True)
)
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.when(
    MockServer::HttpRequest.new(path: '/some/path')
).error(
    MockServer::HttpError.new(drop_connection: true)
)
import mockserver "github.com/mock-server/mockserver-monorepo/mockserver-client-go"

client := mockserver.New("localhost", 1080)
client.When(
    mockserver.Request().Path("/some/path"),
).RespondWithError(
    mockserver.Error().DropConnection(true),
)
using MockServer.Client;
using MockServer.Client.Models;

using var client = new MockServerClient("localhost", 1080);
client.When(
    HttpRequest.Request().WithPath("/some/path")
).Error(
    HttpError.Error().WithDropConnection(true)
);
use mockserver_client::{ClientBuilder, HttpRequest, HttpError};

let client = ClientBuilder::new("localhost", 1080).build().unwrap();
client.when(HttpRequest::new().path("/some/path"))
    .error(HttpError::new().drop_connection(true))
    .unwrap();
use MockServer\MockServerClient;
use MockServer\HttpRequest;
use MockServer\HttpError;

$client = new MockServerClient('localhost', 1080);
$client->when(
    HttpRequest::request()
        ->path('/some/path')
)->error(
    HttpError::error()
        ->dropConnection(true)
);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest" : {
        "path" : "/some/path"
    },
    "httpError" : {
        "dropConnection" : true
    }
}'

See REST API for full JSON specification

Use respondBeforeBody on the request matcher to dispatch the configured response before MockServer reads the request body. The matcher must not include a body matcher and only RESPONSE and ERROR actions are supported. The connection is always closed after the response (the inbound body has not been consumed, so reuse is unsafe), so any closeSocket value is ignored — set keepAliveOverride(false) on the response if you want the Connection: close header on the wire. HTTP/1.1 only — HTTP/2 connections fall through to the standard pipeline. This is useful for reproducing client behaviour when a server responds and closes mid-upload.

new MockServerClient("localhost", 1080)
    .when(
        request()
            .withMethod("POST")
            .withPath("/upload")
            .withRespondBeforeBody(true)
    )
    .respond(
        response()
            .withStatusCode(403)
            .withBody("forbidden")
            .withConnectionOptions(
                connectionOptions().withKeepAliveOverride(false)
            )
    );
from mockserver.client import MockServerClient
from mockserver.models import Expectation

client = MockServerClient("localhost", 1080)
client.upsert(Expectation.from_dict({
    "httpRequest": {
        "method": "POST",
        "path": "/upload",
        "respondBeforeBody": True
    },
    "httpResponse": {
        "statusCode": 403,
        "body": "forbidden",
        "connectionOptions": {
            "keepAliveOverride": False
        }
    }
}))
require 'mockserver-client'

client = MockServer::Client.new('localhost', 1080)
client.upsert(MockServer::Expectation.from_hash({
    "httpRequest": {
        "method": "POST",
        "path": "/upload",
        "respondBeforeBody": true
    },
    "httpResponse": {
        "statusCode": 403,
        "body": "forbidden",
        "connectionOptions": {
            "keepAliveOverride": false
        }
    }
}))
package main

import (
    "bytes"
    "net/http"
)

func main() {
    body := []byte(`{
    "httpRequest": {
        "method": "POST",
        "path": "/upload",
        "respondBeforeBody": true
    },
    "httpResponse": {
        "statusCode": 403,
        "body": "forbidden",
        "connectionOptions": {
            "keepAliveOverride": false
        }
    }
}`)
    req, _ := http.NewRequest("PUT",
        "http://localhost:1080/mockserver/expectation",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    http.DefaultClient.Do(req)
}
using System.Net.Http;
using System.Text;

using var httpClient = new HttpClient();
var json = @"{
    ""httpRequest"": {
        ""method"": ""POST"",
        ""path"": ""/upload"",
        ""respondBeforeBody"": true
    },
    ""httpResponse"": {
        ""statusCode"": 403,
        ""body"": ""forbidden"",
        ""connectionOptions"": {
            ""keepAliveOverride"": false
        }
    }
}";
await httpClient.PutAsync(
    "http://localhost:1080/mockserver/expectation",
    new StringContent(json, Encoding.UTF8, "application/json")
);
use reqwest::blocking::Client;

let client = Client::new();
let body = r#"{
    "httpRequest": {
        "method": "POST",
        "path": "/upload",
        "respondBeforeBody": true
    },
    "httpResponse": {
        "statusCode": 403,
        "body": "forbidden",
        "connectionOptions": {
            "keepAliveOverride": false
        }
    }
}"#;
client.put("http://localhost:1080/mockserver/expectation")
    .header("Content-Type", "application/json")
    .body(body.to_string())
    .send()
    .unwrap();
$json = <<<'JSON'
{
    "httpRequest" : {
        "method" : "POST",
        "path" : "/upload",
        "respondBeforeBody" : true
    },
    "httpResponse" : {
        "statusCode" : 403,
        "body" : "forbidden",
        "connectionOptions" : {
            "keepAliveOverride" : false
        }
    }
}
JSON;

$ch = curl_init('http://localhost:1080/mockserver/expectation');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_POSTFIELDS     => $json,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json; charset=utf-8'],
    CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
curl_close($ch);
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest" : {
        "method" : "POST",
        "path" : "/upload",
        "respondBeforeBody" : true
    },
    "httpResponse" : {
        "statusCode" : 403,
        "body" : "forbidden",
        "connectionOptions" : {
            "keepAliveOverride" : false
        }
    }
}'

See REST API for full JSON specification

For resilience testing of clients that must cope with mid-stream resets, an error action can reset just the matched request stream instead of returning a response. Set streamError to the stream error code to send: over HTTP/2 MockServer sends an RST_STREAM for that stream (RFC 7540 codes, e.g. REFUSED_STREAM = 7), and over HTTP/3 a QUIC RESET_STREAM (RFC 9114 codes, e.g. H3_REQUEST_CANCELLED = 268 / 0x10c). Other streams multiplexed on the same connection are unaffected.

HTTP/1.1 caveat: HTTP/1.1 has no stream concept, so a request that matches over HTTP/1.1 cannot be reset at the stream level — MockServer instead drops the whole connection (the same behaviour as dropConnection).

Precedence: if both streamError and dropConnection are set on the same error action, streamError wins and dropConnection is ignored (over HTTP/1.1 the stream-error fallback drops the connection anyway).

Common stream error codes:

ProtocolNameCode
HTTP/2NO_ERROR0
HTTP/2PROTOCOL_ERROR1
HTTP/2INTERNAL_ERROR2
HTTP/2REFUSED_STREAM7
HTTP/2CANCEL8
HTTP/2ENHANCE_YOUR_CALM11
HTTP/2HTTP_1_1_REQUIRED13
HTTP/3H3_REQUEST_REJECTED267 (0x10b)
HTTP/3H3_REQUEST_CANCELLED268 (0x10c)
HTTP/3H3_INTERNAL_ERROR258 (0x102)
new MockServerClient("localhost", 1080)
    .when(
        request()
            .withPath("/some/path")
    )
    .error(
        error()
            .withStreamError(HttpError.StreamErrorCode.REFUSED_STREAM)
    );

The raw numeric form error().withStreamError(7L) and the error().withStreamErrorCodeName("REFUSED_STREAM") convenience are equivalent.

{
    "httpRequest" : {
        "path" : "/some/path"
    },
    "httpError" : {
        "streamError" : 7
    }
}
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
    "httpRequest" : {
        "path" : "/some/path"
    },
    "httpError" : {
        "streamError" : 7
    }
}'

See REST API for full JSON specification

 

LLM Response

An LLM response action (httpLlmResponse) returns a provider-correct response from a high-level description of what the model should say. Instead of hand-assembling Anthropic or OpenAI response JSON, you describe the intent (text, tool calls, usage, stop reason) and MockServer produces the byte-correct wire format.

Seven providers have full codec support: ANTHROPIC, OPENAI (Chat Completions), OPENAI_RESPONSES, GEMINI, BEDROCK, AZURE_OPENAI, and OLLAMA — each produces the byte-correct wire format for both single completions and streaming. A request naming an unrecognised provider returns a structured 400 response listing the supported providers.

Java Client Example

import static org.mockserver.client.LlmMockBuilder.llmMock;
import static org.mockserver.model.Completion.completion;
import static org.mockserver.model.Provider.ANTHROPIC;
import static org.mockserver.model.ToolUse.toolUse;
import static org.mockserver.model.Usage.usage;

// Simple text completion
llmMock("/v1/messages")
    .withProvider(ANTHROPIC)
    .withModel("claude-sonnet-4")
    .respondingWith(
        completion()
            .withText("The capital of France is Paris.")
            .withStopReason("end_turn")
            .withUsage(usage().withInputTokens(42).withOutputTokens(8))
    )
    .applyTo(mockServerClient);

// Tool / function call
llmMock("/v1/messages")
    .withProvider(ANTHROPIC)
    .respondingWith(
        completion()
            .withText("Let me check the weather.")
            .withToolCall(toolUse("get_weather").withArguments("{\"city\":\"Paris\"}"))
            .withStopReason("tool_use")
    )
    .applyTo(mockServerClient);

JSON Definition Format

{
    "httpRequest": {
        "method": "POST",
        "path": "/v1/messages"
    },
    "httpLlmResponse": {
        "provider": "ANTHROPIC",
        "model": "claude-sonnet-4",
        "completion": {
            "text": "The capital of France is Paris.",
            "stopReason": "end_turn",
            "usage": { "inputTokens": 42, "outputTokens": 8 }
        }
    }
}

Streaming with Realistic Timing

When streaming is enabled, MockServer expands the completion into provider-correct streaming events with configurable timing physics. Most providers use SSE (Server-Sent Events with text/event-stream) — for example, message_start through message_stop for Anthropic, and chat.completion.chunk deltas for OpenAI. Two providers use alternative wire formats: Ollama uses native NDJSON (newline-delimited JSON with application/x-ndjson), and Bedrock uses the AWS event-stream binary framing (application/vnd.amazon.eventstream) where each streaming chunk is a binary message containing a base64-wrapped JSON payload — matching the InvokeModelWithResponseStream wire format. MockServer emits the correct wire format automatically based on the provider.

import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static org.mockserver.client.Llm.jitter;
import static org.mockserver.client.Llm.timeToFirstToken;
import static org.mockserver.client.Llm.tokensPerSecond;
import static org.mockserver.client.LlmMockBuilder.llmMock;
import static org.mockserver.model.Completion.completion;
import static org.mockserver.model.Provider.OPENAI;

llmMock("/v1/chat/completions")
    .withProvider(OPENAI)
    .withModel("gpt-4o")
    .respondingWith(
        completion()
            .withText("Streaming token by token...")
            .streaming()
            .withStreamingPhysics(
                timeToFirstToken(300, MILLISECONDS),
                tokensPerSecond(50),
                jitter(0.2))
    )
    .applyTo(mockServerClient);

Embeddings (Deterministic from Input)

For OpenAI embeddings, deterministicFromInput() generates reproducible vectors seeded from the input text. Same input + same dimensions + same seed produces an identical L2-normalised vector across JVMs.

import static org.mockserver.client.Llm.embedding;
import static org.mockserver.client.LlmMockBuilder.llmMock;
import static org.mockserver.model.Provider.OPENAI;

llmMock("/v1/embeddings")
    .withProvider(OPENAI)
    .respondingWith(
        embedding()
            .withDimensions(1536)
            .deterministicFromInput()
    )
    .applyTo(mockServerClient);

Structured-Output Validation

Attach an outputSchema (a JSON Schema) to a completion and MockServer validates the response text against it as the response is encoded. Validation is fail-soft: a mismatch never changes the response body — it adds an x-mockserver-structured-output-invalid response header and logs a warning, so a malformed structured-output fixture is surfaced without breaking the test (a blank or invalid schema, or a missing text, is a no-op). To assert schema conformance over already-recorded traffic instead, use the verify_structured_output tool.

For a stricter check, set enforceOutputSchema to true alongside the schema. This switches MockServer from fail-soft to strict enforcement: when the configured response does not conform to the schema, the mock fails loudly with a provider-correct error (HTTP 502) instead of returning the non-conforming body. This models a real provider's strict response_format: json_schema mode, where the provider guarantees schema-valid output — so a non-conforming strict fixture is treated as a configuration error rather than passed silently. Enforcement is opt-in; the default (unset, or false) keeps the fail-soft validate-and-log behaviour, and it has no effect without an outputSchema.

import static org.mockserver.client.LlmMockBuilder.llmMock;
import static org.mockserver.model.Completion.completion;
import static org.mockserver.model.Provider.ANTHROPIC;

llmMock("/v1/messages")
    .withProvider(ANTHROPIC)
    .respondingWith(
        completion()
            .withText("{\"city\":\"Paris\",\"country\":\"France\"}")
            .withOutputSchema("{\"type\":\"object\",\"required\":[\"city\",\"country\"]}")
    )
    .applyTo(mockServerClient);

Fault Injection & Rate-Limit Quota

A chaos block on the LLM response injects faults for resilience testing: probabilistic provider errors (e.g. 429/529 with a Retry-After header), mid-stream truncation, malformed SSE, and a stateful request quota. The quota is a deterministic fixed-window rate limit — expectations sharing a quotaName share one counter, so requests past quotaLimit within quotaWindowMillis are rejected with quotaErrorStatus (default 429) and the retryAfter header (the count resets when the window elapses and on server reset). The chaos block is set via the JSON definition (below) or the mock_llm_completion MCP tool, where the full field reference lives.

{
    "httpRequest": {
        "method": "POST",
        "path": "/v1/messages"
    },
    "httpLlmResponse": {
        "provider": "ANTHROPIC",
        "completion": {
            "text": "The capital of France is Paris."
        },
        "chaos": {
            "quotaName": "anthropic-account",
            "quotaLimit": 100,
            "quotaWindowMillis": 60000,
            "quotaErrorStatus": 429,
            "retryAfter": "30"
        }
    }
}

For multi-turn LLM conversations with stateful scenario progression, see the multi-turn LLM conversations section of Stateful Scenarios.

 

WebSocket Response

A WebSocket response action (httpWebSocketResponse) accepts an HTTP Upgrade request and turns the connection into a WebSocket session. Two modes are available:

  • Server-push — a fixed sequence of messages sent to the client immediately after the handshake, defined in the messages array.
  • Bidirectional — incoming WebSocket frames are matched against a list of matchers; the first matching entry triggers its own response sequence. Matchers are evaluated in order; first match wins.

Both modes can be combined in a single expectation: MockServer sends any messages immediately after the upgrade, then waits for incoming frames and applies matchers for each one received.

Bidirectional Frame Matching

Each entry in the matchers array contains:

  • frameType — the WebSocket frame type to match: TEXT, BINARY, PING, PONG, or ANY (matches any type).
  • textMatcher — optional substring or exact string the text frame payload must contain. Omit to match all frames of the given frameType.
  • responses — the sequence of messages to send back when this matcher fires. Each entry has a text field (and an optional delay).

JSON Definition Format

{
    "httpRequest": {
        "method": "GET",
        "path": "/ws/chat"
    },
    "httpWebSocketResponse": {
        "messages": [
            {"text": "{\"type\": \"connected\"}"}
        ],
        "matchers": [
            {
                "frameType": "TEXT",
                "textMatcher": "ping",
                "responses": [
                    {"text": "{\"type\": \"pong\"}"}
                ]
            },
            {
                "frameType": "TEXT",
                "textMatcher": "subscribe",
                "responses": [
                    {"text": "{\"type\": \"ack\"}"},
                    {"text": "{\"type\": \"data\", \"value\": 42}"}
                ]
            }
        ],
        "closeConnection": false
    }
}

In this example, MockServer sends {"type": "connected"} immediately after the WebSocket upgrade. If the client then sends a frame containing ping, MockServer replies with {"type": "pong"}. A frame containing subscribe triggers a two-message reply sequence. Frames that match no entry are silently ignored.

Bidirectional WebSocket expectations are also authorable in the dashboard Composer — select WebSocket response as the action type and use the Bidirectional frame matchers panel to add entries.

 

CRUD Simulation

CRUD Simulation lets you quickly stand up a fully functional RESTful resource without writing individual expectations for each HTTP method. You provide a base path and optional configuration, and MockServer automatically generates five endpoints that manage an in-memory collection of JSON objects.

This is useful when your tests need a realistic data store (e.g. users, products, orders) that supports create, read, update, and delete operations without manually defining expectations for each verb.

Auto-Generated Endpoints

Given a basePath of /api/users, MockServer generates:

MethodPathDescriptionSuccess Status
GET/api/usersList all items200
POST/api/usersCreate a new item201
GET/api/users/{id}Get item by ID200
PUT/api/users/{id}Update item by ID200
DELETE/api/users/{id}Delete item by ID204

JSON Definition Format

A CRUD simulation is defined by a JSON object with the following fields:

  • basePath (required) - the URL path prefix for the generated endpoints, e.g. /api/users
  • idField (optional, default "id") - the field name used as the unique identifier in each JSON object
  • idStrategy (optional, default "AUTO_INCREMENT") - how IDs are generated for new items:
    • AUTO_INCREMENT - sequential numeric IDs (1, 2, 3, ...)
    • UUID - random UUID strings
  • initialData (optional) - an array of JSON objects to pre-populate the data store

REST API

Register a CRUD simulation using PUT /mockserver/crud:

curl -X PUT "http://localhost:1080/mockserver/crud" \
  -H "Content-Type: application/json" \
  -d '{
    "basePath": "/api/users",
    "idField": "id",
    "idStrategy": "AUTO_INCREMENT",
    "initialData": [
      {"name": "Alice", "email": "alice@example.com"},
      {"name": "Bob", "email": "bob@example.com"}
    ]
  }'

After registration, the endpoints are immediately available:

# List all users
curl http://localhost:1080/api/users

# Create a new user
curl -X POST http://localhost:1080/api/users \
  -H "Content-Type: application/json" \
  -d '{"name": "Charlie", "email": "charlie@example.com"}'

# Get user by ID
curl http://localhost:1080/api/users/1

# Update user
curl -X PUT http://localhost:1080/api/users/1 \
  -H "Content-Type: application/json" \
  -d '{"name": "Alice Updated", "email": "alice@example.com"}'

# Delete user
curl -X DELETE http://localhost:1080/api/users/3

Java Client Example

new MockServerClient("localhost", 1080)
    .crud(
        new CrudExpectationsDefinition()
            .withBasePath("/api/users")
            .withIdField("id")
            .withIdStrategy(CrudExpectationsDefinition.IdStrategy.AUTO_INCREMENT)
    );

UUID ID Strategy Example

curl -X PUT "http://localhost:1080/mockserver/crud" \
  -H "Content-Type: application/json" \
  -d '{
    "basePath": "/api/products",
    "idStrategy": "UUID"
  }'

# Create a product - ID will be a UUID like "550e8400-e29b-41d4-a716-446655440000"
curl -X POST http://localhost:1080/api/products \
  -H "Content-Type: application/json" \
  -d '{"name": "Widget", "price": 9.99}'

CRUD simulations are independent of regular expectations and are cleared when MockServer is reset. You can register multiple CRUD simulations with different base paths simultaneously.

 

Next Steps

  • Verify Requests — assert that your code under test sent the requests you expected, with the right headers, body, and call count
  • Troubleshoot Matching — work out why a request did not match the expectation you configured
  • Response Templates — build dynamic responses from the incoming request using Velocity, Mustache, or JavaScript templates
  • Before & After Actions — fire extra HTTP webhooks or callbacks before or after an expectation's response to mirror, shadow, fan-out, or gate live traffic
  • Clearing & Resetting — remove expectations and recorded requests between tests to keep state isolated
  • Persisting Expectations — save and reload expectations so they survive restarts