Client Capability Matrix and Test Usage
All eight MockServer clients cover the core control-plane API (expectations, verification, clear/reset, retrieve). Feature coverage diverges for higher-level capabilities. Use the matrix below to pick a client and jump to the idiomatic test-fixture snippet for your language.
Capability Matrix
Key: ✅ supported | — not available
| Feature | Java | Node | Python | Ruby | Go | .NET | Rust | PHP |
|---|---|---|---|---|---|---|---|---|
| Expectations (create / upsert) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Verify requests | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| OpenAPI expectations | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| LLM mock builder | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| MCP mock builder | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Test fixture / auto-cleanup | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | — | ✅ |
| retrieveAsCode | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Testcontainers module | ✅ | ✅ | ✅ | — | ✅ | ✅ | ✅ | — |
| Load scenario (start / status / stop) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
Notes on specific cells:
- Rust — test fixture: the Rust client has no built-in auto-reset helper. Use the Testcontainers module and call
client.reset()manually at the start of each test. - Ruby / PHP — Testcontainers: no official MockServer Testcontainers module for these languages. Use Docker Compose or the binary launcher instead.
Using MockServer in Tests — Per-Language Fixtures
The snippets below show the idiomatic way to wire MockServer into each language's test framework so that recorded requests, expectations, and logs are reset between tests and connections are cleaned up automatically.
Java — JUnit 5 (@ExtendWith(MockServerExtension.class))
The mockserver-junit-jupiter artifact provides a JUnit 5 extension that starts a ClientAndServer and injects a MockServerClient into each test method. Add mockserver-junit-jupiter to your test dependencies:
import org.mockserver.client.MockServerClient;
import org.mockserver.junit.jupiter.MockServerExtension;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import static org.mockserver.model.HttpRequest.request;
import static org.mockserver.model.HttpResponse.response;
@ExtendWith(MockServerExtension.class)
class PaymentServiceTest {
@Test
void returnsPaymentConfirmation(MockServerClient client) {
client.when(
request().withMethod("POST").withPath("/payments")
).respond(
response().withStatusCode(201).withBody("{\"id\":\"pay_001\"}")
);
// ... call the system under test ...
client.verify(request().withPath("/payments"));
}
}
For JUnit 4, use mockserver-junit-rule and annotate a field with @Rule MockServerRule rule = new MockServerRule(this).
Node / TypeScript — await using (Symbol.asyncDispose)
The Node client implements Symbol.asyncDispose, so any runtime that supports the TC39 Explicit Resource Management proposal (Node.js 20+, TypeScript 5.2+) can use await using to reset the server automatically when the test scope exits:
import { mockServerClient } from 'mockserver-client';
describe('payment service', () => {
it('records a payment request', async () => {
await using client = mockServerClient('localhost', 1080);
await client.mockSimpleResponse('/payments', { id: 'pay_001' }, 201);
// ... call the system under test ...
await client.verify({ path: '/payments' }, 1, 1);
// client[Symbol.asyncDispose]() fires automatically on scope exit
});
});
On runtimes that do not yet support Symbol.asyncDispose, call client.stop() (which also resets) in an afterEach hook instead.
Python — pytest conftest.py fixture
Define a session-scoped fixture that locates MockServer and a test-scoped fixture that provides a reset client for each test. Place these in your conftest.py:
import os
import pytest
from mockserver import MockServerClient
@pytest.fixture(scope="session")
def mockserver_url():
host = os.environ.get("MOCKSERVER_HOST", "localhost")
port = int(os.environ.get("MOCKSERVER_PORT", "1080"))
yield host, port
@pytest.fixture()
def mockserver_client(mockserver_url):
host, port = mockserver_url
with MockServerClient(host, port) as client:
client.reset()
yield client
client.reset()
Use the fixture in tests:
from mockserver import HttpRequest, HttpResponse, VerificationTimes
def test_payment(mockserver_client):
mockserver_client.when(
HttpRequest.request("/payments").with_method("POST")
).respond(
HttpResponse.response('{"id":"pay_001"}', status_code=201)
)
# ... call the system under test ...
mockserver_client.verify(
HttpRequest.request("/payments"),
VerificationTimes.at_least(1)
)
Ruby — RSpec shared context (:mockserver tag)
Require mockserver/rspec from your spec_helper.rb to register a shared context. Tag any example group with :mockserver to receive a memoised, pre-reset mockserver client that is reset before and after each example:
# spec_helper.rb
require 'mockserver/rspec'
# spec/payment_service_spec.rb
RSpec.describe PaymentService, :mockserver do
# Override host/port if needed:
# let(:mockserver_host) { 'localhost' }
# let(:mockserver_port) { 1080 }
it 'sends a POST to /payments' do
mockserver.when(
MockServer::HttpRequest.request(path: '/payments').with_method('POST')
).respond(
MockServer::HttpResponse.response(body: '{"id":"pay_001"}', status_code: 201)
)
# ... call the system under test ...
mockserver.verify(
MockServer::HttpRequest.request(path: '/payments'),
times: MockServer::VerificationTimes.at_least(1)
)
end
end
The host and port default to 127.0.0.1:1080 and can be overridden with the MOCKSERVER_HOST / MOCKSERVER_PORT environment variables, or by defining a mockserver_host / mockserver_port let in your example group.
Go — MockServerT / t.Cleanup
mockserver.NewMockServerT(t, host, port) creates a client and registers a t.Cleanup that calls Reset() when the test (and any sub-tests) finish. Use MockServerT(t, client) to attach the cleanup to an existing client:
package payment_test
import (
"testing"
mockserver "github.com/mock-server/mockserver-monorepo/mockserver-client-go"
)
func TestPayment(t *testing.T) {
client := mockserver.NewMockServerT(t, "localhost", 1080)
client.When(
mockserver.Request().Method("POST").Path("/payments"),
).Respond(
mockserver.Response().StatusCode(201).Body(`{"id":"pay_001"}`),
)
// ... call the system under test ...
client.Verify(mockserver.Request().Path("/payments"), mockserver.AtLeast(1))
// client.Reset() runs automatically via t.Cleanup when the test ends
}
.NET — MockServerFixture (IAsyncLifetime)
MockServerFixture from the MockServer.Client.IntegrationTests namespace implements xUnit's IAsyncLifetime interface. Derive your test class from it to get a Client property that is reset before and after the test class runs. Set the MOCKSERVER_URL environment variable (for example http://localhost:1080) before running tests:
using MockServer.Client.IntegrationTests;
using MockServer.Client;
using MockServer.Client.Models;
using Xunit;
public class PaymentServiceTests : MockServerFixture
{
[SkippableFact]
public async Task RecordsPaymentRequest()
{
SkipIfNoServer(); // skip gracefully when MOCKSERVER_URL is not set
Client!.When(
HttpRequest.Request().WithMethod("POST").WithPath("/payments")
).Respond(
HttpResponse.Response().WithStatusCode(201).WithBody("{\"id\":\"pay_001\"}")
);
// ... call the system under test ...
await Client.VerifyAsync(
HttpRequest.Request().WithPath("/payments"),
VerificationTimes.AtLeastTimes(1)
);
}
}
Rust — manual reset (no built-in fixture)
The Rust client has no built-in test fixture helper. The recommended pattern is to use the Testcontainers module to start a dedicated MockServer container and call client.reset() at the start of each test:
use mockserver_client::{ClientBuilder, HttpRequest, HttpResponse, VerificationTimes};
use testcontainers::runners::SyncRunner;
use testcontainers_mockserver::MockServer as MockServerImage;
#[test]
#[ignore = "requires Docker"]
fn records_payment_request() {
let container = MockServerImage::default().start().unwrap();
let base_url = testcontainers_mockserver::base_url(&container);
let client = ClientBuilder::from_base_url(&base_url).build().unwrap();
client.reset().unwrap();
client.when(HttpRequest::new().method("POST").path("/payments"))
.respond(HttpResponse::new().status_code(201).body(r#"{"id":"pay_001"}"#))
.unwrap();
// ... call the system under test ...
client.verify(
HttpRequest::new().path("/payments"),
VerificationTimes::at_least(1),
).unwrap();
// container is dropped here -- MockServer stops automatically
}
PHP — MockServerTestTrait (PHPUnit)
Mix MockServer\Testing\MockServerTestTrait into your PHPUnit test case and call the lifecycle helpers from setUp() and tearDown(). The trait provides $this->mockServer as a reset client. Set the MOCKSERVER_URL environment variable (for example http://localhost:1080) before running tests:
use MockServer\Testing\MockServerTestTrait;
use PHPUnit\Framework\TestCase;
final class PaymentServiceTest extends TestCase
{
use MockServerTestTrait;
protected function setUp(): void
{
$this->setUpMockServer();
}
protected function tearDown(): void
{
$this->tearDownMockServer();
}
public function testRecordsPaymentRequest(): void
{
$this->mockServer->when(
\MockServer\HttpRequest::request()->method('POST')->path('/payments')
)->respond(
\MockServer\HttpResponse::response()->statusCode(201)->body('{"id":"pay_001"}')
);
// ... call the system under test ...
$this->mockServer->verify(
\MockServer\HttpRequest::request()->path('/payments'),
\MockServer\VerificationTimes::atLeast(1)
);
}
}