Note: this page is a high level overview of each topic, more detail is available for each topic on a linked page.

To use MockServer to analysis an existing system:

  1. Start MockServer
  2. Configure Clients
  3. Run Scenarios
  4. Analyse Behaviour

Mocking service dependencies with MockServer

To use MockServer to verify requests:

  1. Start MockServer
  2. Configure Clients
  3. Run Your Test Scenarios
  4. Verify Requests

Mocking service dependencies with MockServer

For example code see the code examples folder in the git repository.

Inspecting AI agent traffic? If you want to see the HTTPS calls that Claude Code, OpenCode, or Python AI libraries send to LLM APIs and MCP servers, see Inspect AI Agent Traffic. It covers proxy setup, CA trust, and per-tool configuration for AI tools.

 

0. Start MockServer

MockServer is flexible and support numerous usage patterns.

MockServer can be run:

To simplify configuration all versions (except the deployable WAR) use a single port to support the control plane and data plane in HTTP, HTTPS or SOCKS.

MockServer is available in the following formats:

It is also possible to build and run MockServer directly from source code

MockServer UI:

MockServer has a UI that can be used to view the internal state within MockServer, including:

 

1. Configure Clients

The page on configuring clients gives full details on how to configure clients to proxy requests via MockServer and includes code examples for the following clients:

 

3. Analysing Behaviour

To analyse the requests that a system makes the proxy can be used to record all requests and their corresponding responses.

All requests and responses can be retrieved as expectations (called recorded expectations) in Java code or JSON. This allows an easy way to replay a recording from the proxy.

Unlike conventional record-replay approaches typically provided by other proxies, MockServer allows easy editing of the recorded requests because the recording is provided as Java code or JSON. This ensures that if minor changes are made to an API the recording can easily be modified and no re-recording required avoiding the need to update test assertions.

 

HAR Export

Recorded requests and responses can be exported as a HAR (HTTP Archive) 1.2 file, which is a standard format supported by browser DevTools and other HTTP analysis tools.

To export as HAR, use the retrieve API with type=REQUEST_RESPONSES and format=HAR:

curl -v -X PUT "http://localhost:1080/mockserver/retrieve?type=REQUEST_RESPONSES&format=HAR"
 

Automatic Persistence of Recorded Expectations

By default, recorded proxy traffic is only held in memory and lost when MockServer restarts. To automatically persist recorded expectations to a JSON file, configure the following properties:

  • persistRecordedExpectations - set to true to enable automatic persistence of recorded expectations
  • persistedRecordedExpectationsPath - file path for saving the recorded expectations (default: persistedRecordedExpectations.json)

The file is updated whenever a new request is forwarded through the proxy. The saved file can be loaded back into MockServer using the initializationJsonPath property to replay the recorded traffic.

 

Retrieving Recorded Expectations

All proxied requests including those proxied using a forward actions are recorded containing the request received and response returned.

It is possible to retrieve the recorded requests and responses as expectations so that they can be easily used as expectations to simulation a system.

Expectations are returned in the order they have been recorded. The expectations are returned can be filter using a request matcher.

Expectation[] recordedExpectations = new MockServerClient("localhost", 1080)
    .retrieveRecordedExpectations(
        request()
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080)
    .retrieveRecordedExpectations({})
    .then(
        function (recordedExpectations) {
            console.log(JSON.stringify(recordedExpectations));
        },
        function (error) {
            console.log(error);
        }
    );

See REST API for full JSON specification

curl -v -X PUT "http://localhost:1080/mockserver/retrieve?type=RECORDED_EXPECTATIONS"

See REST API for full JSON specification

Expectation[] recordedExpectations = new MockServerClient("localhost", 1080)
    .retrieveRecordedExpectations(
        request()
            .withPath("/some/path")
            .withMethod("POST")
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).retrieveRecordedExpectations({
    "path": "/some/path",
    "method": "POST"
}).then(
    function (recordedExpectations) {
        console.log(JSON.stringify(recordedExpectations));
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

curl -v -X PUT "http://localhost:1080/mockserver/retrieve?type=RECORDED_EXPECTATIONS" -d '{
    "path": "/some/path",
    "method": "POST"
}'

See REST API for full JSON specification

String recordedExpectations = new MockServerClient("localhost", 1080)
    .retrieveRecordedExpectations(
        request()
            .withPath("/some/path")
            .withMethod("POST"),
        Format.JAVA
    );
curl -v -X PUT "http://localhost:1080/mockserver/retrieve?type=RECORDED_EXPECTATIONS&format=JAVA" -d '{
    "path": "/some/path"
}'

See REST API for full JSON specification

String recordedExpectations = new MockServerClient("localhost", 1080)
    .retrieveRecordedExpectations(
        request()
            .withPath("/some/path")
            .withMethod("POST"),
        Format.JSON
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).retrieveRecordedExpectations({
    "path": "/some/path",
    "method": "POST"
}).then(
    function (recordedExpectations) {
        console.log(JSON.stringify(recordedExpectations));
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

curl -v -X PUT "http://localhost:1080/mockserver/retrieve?type=RECORDED_EXPECTATIONS&format=JSON" -d '{
    "path": "/some/path"
}'

See REST API for full JSON specification

 

Retrieving Recorded Requests

All requests the MockServer receives are recorded, including both proxied requests and requests that have matched an expectation.

It is possible to retrieve the recorded requests, as show below in the code examples.

Requests are returned in the order they have been recorded. Which requests are returned can be filter using a request matcher.

HttpRequest[] recordedRequests = new MockServerClient("localhost", 1080)
    .retrieveRecordedRequests(
        request()
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080)
    .retrieveRecordedRequests({})
    .then(
        function (recordedRequests) {
            console.log(JSON.stringify(recordedRequests));
        },
        function (error) {
            console.log(error);
        }
    );

See REST API for full JSON specification

curl -v -X PUT "http://localhost:1080/mockserver/retrieve?type=REQUESTS"

See REST API for full JSON specification

HttpRequest[] recordedRequests = new MockServerClient("localhost", 1080)
    .retrieveRecordedRequests(
        request()
            .withPath("/some/path")
            .withMethod("POST")
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).retrieveRecordedRequests({
    "path": "/some/path",
    "method": "POST"
}).then(
    function (recordedRequests) {
        console.log(JSON.stringify(recordedRequests));
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

curl -v -X PUT "http://localhost:1080/mockserver/retrieve?type=REQUESTS" -d '{
    "path": "/some/path",
    "method": "POST"
}'

See REST API for full JSON specification

String recordedRequests = new MockServerClient("localhost", 1080)
    .retrieveRecordedRequests(
        request()
            .withPath("/some/path")
            .withMethod("POST"),
        Format.JAVA
    );
curl -v -X PUT "http://localhost:1080/mockserver/retrieve?type=REQUESTS&format=JAVA" -d '{
    "path": "/some/path"
}'

See REST API for full JSON specification

String recordedRequests = new MockServerClient("localhost", 1080)
    .retrieveRecordedRequests(
        request()
            .withPath("/some/path")
            .withMethod("POST"),
        Format.JSON
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).retrieveRecordedRequests({
    "path": "/some/path",
    "method": "POST"
}).then(
    function (recordedRequests) {
        console.log(JSON.stringify(recordedRequests));
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

curl -v -X PUT "http://localhost:1080/mockserver/retrieve?type=REQUESTS&format=JSON" -d '{
    "path": "/some/path"
}'

See REST API for full JSON specification

 

Retrieve Recorded Requests & Responses

All requests the MockServer receives are recorded, including both proxied requests and requests that have matched an expectation.

It is possible to retrieve the recorded requests and their responses, as show below in the code examples.

Requests and responses are returned in the order they have been recorded. Which requests are returned can be filter using a request matcher.

HttpRequestAndHttpResponse[] httpRequestAndHttpResponse = new MockServerClient("localhost", 1080)
    .retrieveRecordedRequestsAndResponses(
        request()
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080)
    .retrieveRecordedRequestsAndResponses({})
    .then(
        function (recordedRequestsAndResponses) {
            console.log(JSON.stringify(recordedRequestsAndResponses));
        },
        function (error) {
            console.log(error);
        }
    );

See REST API for full JSON specification

curl -v -X PUT "http://localhost:1080/mockserver/retrieve?type=REQUEST_RESPONSES"

See REST API for full JSON specification

HttpRequestAndHttpResponse[] httpRequestAndHttpResponse = new MockServerClient("localhost", 1080)
    .retrieveRecordedRequestsAndResponses(
        request()
            .withPath("/some/path")
            .withMethod("POST")
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).retrieveRecordedRequestsAndResponses({
    "path": "/some/path",
    "method": "POST"
}).then(
    function (recordedRequestsAndResponses) {
        console.log(JSON.stringify(recordedRequestsAndResponses));
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

curl -v -X PUT "http://localhost:1080/mockserver/retrieve?type=REQUEST_RESPONSES" -d '{
    "path": "/some/path",
    "method": "POST"
}'

See REST API for full JSON specification

String har = new MockServerClient("localhost", 1080)
    .retrieveRecordedRequestsAndResponses(
        request(),
        Format.HAR
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080)
    .retrieveRecordedRequestsAndResponsesAsHar({})
    .then(
        function (har) {
            console.log(JSON.stringify(har));
        },
        function (error) {
            console.log(error);
        }
    );

See REST API for full JSON specification

curl -v -X PUT "http://localhost:1080/mockserver/retrieve?type=REQUEST_RESPONSES&format=HAR"

See REST API for full JSON specification

String har = new MockServerClient("localhost", 1080)
    .retrieveRecordedRequestsAndResponses(
        request()
            .withPath("/some/path")
            .withMethod("POST"),
        Format.HAR
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080).retrieveRecordedRequestsAndResponsesAsHar({
    "path": "/some/path",
    "method": "POST"
}).then(
    function (har) {
        console.log(JSON.stringify(har));
    },
    function (error) {
        console.log(error);
    }
);

See REST API for full JSON specification

curl -v -X PUT "http://localhost:1080/mockserver/retrieve?type=REQUEST_RESPONSES&format=HAR" -d '{
    "path": "/some/path",
    "method": "POST"
}'

See REST API for full JSON specification

3. Verify Requests

MockServer supports verification of requests it has received, including both proxied requests and requests that have matched an expectation.

Verification can be specified as follows:

 

How Verification Works

MockServer records all received requests in an in-memory event log (separate from application logs). Verification checks this event log:

For request matcher count verification: MockServer filters the event log to find all RECEIVED_REQUEST entries matching your request matcher, counts them, and compares the count against your constraint (atLeast(n), exactly(n), etc.). Returns HTTP 202 if the count matches, or HTTP 406 with an error message if it does not.

For expectation ID verification: MockServer retrieves all events associated with the specified expectation ID (including EXPECTATION_RESPONSE and FORWARDED_REQUEST entries) and verifies the count.

For sequence verification: MockServer scans recorded requests in order, checking that each expected request appears after the previous match. This is not a simple count comparison—order matters.

Important notes for parallel testing:

  • The event log size is bounded by the maxLogEntries configuration property (default: minimum of free heap KB / 8 and 100,000 entries—see configuration). When this limit is reached, the oldest entries are evicted. If you run many parallel tests generating thousands of requests, consider increasing this value.
  • Event recording uses an asynchronous ring buffer. However, verification operations are serialized through the same ring buffer in FIFO order, so a request that has reached MockServer and been recorded will be visible to subsequent verification calls. Intermittent failures are more commonly caused by:
    • Your application under test sending requests asynchronously—ensure the application has completed sending before you verify
    • Cross-test interference—one test's requests appearing in another test's verification
    • Log eviction due to high request volume exceeding maxLogEntries
  • Best practices for parallel tests:
    • Use separate MockServer instances (different ports or containers) per test for complete isolation
    • If sharing an instance, use unique paths per test (e.g., /test/{testId}/...) or unique headers/query parameters in matchers
    • Avoid broad matchers like only path("/api") in parallel tests
    • Be careful with clear() or reset()—they affect all tests sharing the instance
    • If verification fails intermittently because your system under test is asynchronous, use retry-with-backoff to wait for requests to arrive (not to wait for MockServer to process already-received requests)
  • To retrieve recorded requests for debugging, use PUT /mockserver/retrieve?type=REQUESTS or mockServerClient.retrieveRecordedRequests(null).

For more details on the internal architecture, see the Event System documentation.

 

Verification Timing

Note: MockServer processes log entries asynchronously using a ring buffer. When calling verify() immediately after sending requests, there may be a brief delay before log entries are available for verification. If verification fails unexpectedly right after requests are sent, add a small delay (e.g., 100ms) before retrying. This is most commonly needed in high-throughput scenarios or when the system under test sends requests asynchronously.

Verifying Repeating Requests

Verify that a request has been received by MockServer a specific number of times using a Verification

new MockServerClient("localhost", 1080)
    .verify(
        request()
            .withPath("/some/path"),
        VerificationTimes.atLeast(2)
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080)
  .verify(
    {
      'path': '/some/path'
    }, 2)
  .then(
    function () {
      console.log("request found at least 2 times");
    },
    function (error) {
      console.log(error);
    }
  );

See REST API for full JSON specification

curl -v -X PUT "http://localhost:1080/mockserver/verify" -d '{
    "httpRequest": {
        "path": "/simple"
    },
    "times": {
        "atLeast": 2
    }
}'

See REST API for full JSON specification

new MockServerClient("localhost", 1080)
.verify(
    request()
        .withPath("/some/path"),
    VerificationTimes.atMost(2)
);
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080)
.verify(
{
  'path': '/some/path'
}, 0, 2)
.then(
function () {
  console.log("request found at most 2 times");
},
function (error) {
  console.log(error);
}
);

See REST API for full JSON specification

curl -v -X PUT "http://localhost:1080/mockserver/verify" -d '{
    "httpRequest": {
        "path": "/simple"
    },
    "times": {
        "atMost": 2
    }
}'

See REST API for full JSON specification

new MockServerClient("localhost", 1080)
    .verify(
        request()
            .withPath("/some/path"),
        VerificationTimes.exactly(2)
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080)
  .verify(
    {
      'path': '/some/path'
    }, 2, 2)
    .then(
        function () {
            console.log("request found exactly 1 time");
        },
        function (error) {
            console.log(error);
        }
    );

See REST API for full JSON specification

curl -v -X PUT "http://localhost:1080/mockserver/verify" -d '{
    "httpRequest": {
        "path": "/simple"
    },
    "times": {
        "atLeast": 2,
        "atMost": 2
    }
}'

See REST API for full JSON specification

new MockServerClient("localhost", 1080)
    .verify(
        openAPI(
            "https://raw.githubusercontent.com/mock-server/mockserver-monorepo/master/mockserver/mockserver-integration-testing/src/main/resources/org/mockserver/openapi/openapi_petstore_example.json"
        ),
        VerificationTimes.atLeast(2)
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080)
    .verify(
        {
            'specUrlOrPayload': 'https://raw.githubusercontent.com/mock-server/mockserver-monorepo/master/mockserver/mockserver-integration-testing/src/main/resources/org/mockserver/openapi/openapi_petstore_example.json'
        }, 2)
    .then(
        function () {
            console.log("request found exactly 2 times");
        },
        function (error) {
            console.log(error);
        }
    );

See REST API for full JSON specification

curl -v -X PUT "http://localhost:1080/mockserver/verify" -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"
    },
    "times": {
        "atLeast": 2
    }
}'

See REST API for full JSON specification

new MockServerClient("localhost", 1080)
    .verify(
        openAPI(
            "org/mockserver/openapi/openapi_petstore_example.json",
            "showPetById"
        ),
        VerificationTimes.once()
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080)
    .verify(
        {
            'specUrlOrPayload': 'org/mockserver/openapi/openapi_petstore_example.json',
            'operationId': 'showPetById'
        }, 1, 1)
    .then(
        function () {
            console.log("request found exactly 2 times");
        },
        function (error) {
            console.log(error);
        }
    );

See REST API for full JSON specification

curl -v -X PUT "http://localhost:1080/mockserver/verify" -d '{
    "httpRequest": {
        "specUrlOrPayload": "org/mockserver/openapi/openapi_petstore_example.json",
        "operationId": "showPetById"
    },
    "times": {
        "atLeast": 1,
        "atMost": 1
    }
}'

See REST API for full JSON specification

new MockServerClient("localhost", 1080)
    .verify(
        "31e4ca35-66c6-4645-afeb-6e66c4ca0559",
        VerificationTimes.once()
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080)
    .verifyById(
        {
            'id': '31e4ca35-66c6-4645-afeb-6e66c4ca0559'
        }, 1, 1)
    .then(
        function () {
            console.log("request found exactly 1 time");
        },
        function (error) {
            console.log(error);
        }
    );

See REST API for full JSON specification

curl -v -X PUT "http://localhost:1080/mockserver/verify" -d '{
            "id": "31e4ca35-66c6-4645-afeb-6e66c4ca0559"
        }'

See REST API for full JSON specification

new MockServerClient("localhost", 1080)
    .verify(
        request()
            .withPath("/some/path"),
        VerificationTimes.exactly(0)
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080)
  .verify(
    {
      'path': '/some/path'
    }, 0, true)
  .then(
    function () {
      console.log("request found zero times");
    },
    function (error) {
      console.log(error);
    }
  );

See REST API for full JSON specification

curl -v -X PUT "http://localhost:1080/mockserver/verify" -d '{
    "httpRequest": {
        "path": "/simple"
    },
    "times": {
        "atMost": 0
    }
}'

See REST API for full JSON specification

Verifying Request Sequences

Verify that a sequence of requests has been received by MockServer in the specified order using a VerificationSequence

The each request in the sequence will be verified to have been received at least once, in the exact order specified.

new MockServerClient("localhost", 1080)
    .verify(
        request()
            .withPath("/some/path/one"),
        request()
            .withPath("/some/path/two"),
        request()
            .withPath("/some/path/three")
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080)
  .verifySequence(
    {
      'path': '/some/path/one'
    },
    {
      'path': '/some/path/two'
    },
    {
      'path': '/some/path/three'
    }
  )
  .then(
    function () {
      console.log("request sequence found in the order specified");
    },
    function (error) {
      console.log(error);
    }
  );

See REST API for full JSON specification

curl -v -X PUT "http://localhost:1080/mockserver/verifySequence" -d '{
   "httpRequests":[
      {
         "path":"/some/path/one"
      },
      {
         "path":"/some/path/two"
      },
      {
         "path":"/some/path/three"
      }
   ]
}'

See REST API for full JSON specification

new MockServerClient("localhost", 1080)
    .verify(
        request()
            .withPath("/status"),
        openAPI(
            "org/mockserver/openapi/openapi_petstore_example.json",
            "listPets"
        ),
        openAPI(
            "org/mockserver/openapi/openapi_petstore_example.json",
            "showPetById"
        )
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080)
    .verifySequence(
        {
            'path': '/status'
        },
        {
            'specUrlOrPayload': 'org/mockserver/openapi/openapi_petstore_example.json',
            'operationId': 'listPets'
        },
        {
            'specUrlOrPayload': 'org/mockserver/openapi/openapi_petstore_example.json',
            'operationId': 'showPetById'
        }
    )
    .then(
        function () {
            console.log("request sequence found in the order specified");
        },
        function (error) {
            console.log(error);
        }
    );

See REST API for full JSON specification

curl -v -X PUT "http://localhost:1080/mockserver/verifySequence" -d '{
   "httpRequests":[
      {
         "path": "/status"
      },
      {
         "specUrlOrPayload": "org/mockserver/openapi/openapi_petstore_example.json",
         "operationId": "listPets"
      },
      {
         "specUrlOrPayload": "org/mockserver/openapi/openapi_petstore_example.json",
         "operationId": "showPetById"
      }
   ]
}'

See REST API for full JSON specification

new MockServerClient("localhost", 1080)
    .verify(
        "31e4ca35-66c6-4645-afeb-6e66c4ca0559",
        "66c6ca35-ca35-66f5-8feb-5e6ac7ca0559",
        "ca3531e4-23c8-ff45-88f5-4ca0c7ca0559"
    );
var mockServerClient = require('mockserver-client').mockServerClient;
mockServerClient("localhost", 1080)
    .verifySequenceById(
        {
            'id': '31e4ca35-66c6-4645-afeb-6e66c4ca0559'
        },
        {
            'id': '66c6ca35-ca35-66f5-8feb-5e6ac7ca0559'
        },
        {
            'id': 'ca3531e4-23c8-ff45-88f5-4ca0c7ca0559'
        }
    )
    .then(
        function () {
            console.log("request sequence found in the order specified");
        },
        function (error) {
            console.log(error);
        }
    );

See REST API for full JSON specification

curl -v -X PUT "http://localhost:1080/mockserver/verifySequence" -d '{
    "httpRequests": [
        {
            "id": "31e4ca35-66c6-4645-afeb-6e66c4ca0559"
        },
        {
            "id": "66c6ca35-ca35-66f5-8feb-5e6ac7ca0559"
        },
        {
            "id": "ca3531e4-23c8-ff45-88f5-4ca0c7ca0559"
        }
    ]
}'

See REST API for full JSON specification