PHP code example of mock-server / mockserver-client

1. Go to this page and download the library: Download mock-server/mockserver-client library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

mock-server / mockserver-client example snippets




use MockServer\MockServerClient;
use MockServer\HttpRequest;
use MockServer\HttpResponse;
use MockServer\VerificationTimes;

// Connect to MockServer
$client = new MockServerClient('localhost', 1080);

// Create an expectation
$client->when(
    HttpRequest::request()->method('GET')->path('/hello')
)->respond(
    HttpResponse::response()
        ->statusCode(200)
        ->header('Content-Type', 'application/json')
        ->body('{"message":"world"}')
);

// Verify the request was received
$client->verify(
    HttpRequest::request()->path('/hello'),
    VerificationTimes::atLeast(1)
);

// Reset all expectations
$client->reset();

use MockServer\Times;
use MockServer\TimeToLive;
use MockServer\Delay;
use MockServer\HttpForward;

// Respond with a delay
$client->when(
    HttpRequest::request()->method('POST')->path('/api/data')
        ->header('Content-Type', 'application/json')
        ->jsonBody(['key' => 'value'])
)->respond(
    HttpResponse::response()
        ->statusCode(201)
        ->body('{"id": 1}')
        ->delay(Delay::milliseconds(500))
);

// Match only 3 times, with priority
$client->when(
    HttpRequest::request()->path('/limited'),
    Times::exactly(3),
    TimeToLive::exactly('SECONDS', 60),
    priority: 10
)->respond(
    HttpResponse::response()->statusCode(200)
);

// Forward to another server
$client->when(
    HttpRequest::request()->path('/proxy')
)->forward(
    HttpForward::forward()->host('backend.local')->port(8080)->scheme('HTTP')
);

use MockServer\Jwt;

$client->when(
    HttpRequest::request()->method('GET')->path('/secure')
        ->jwt(
            Jwt::jwt()
                ->claim('sub', 'user-123')          // exact match
                ->claim('role', '!admin')           // negated match
                ->claim('email', '^[email protected]$') // regex match
                ->issuer('https://issuer.example.com')
                ->audience('my-api')
                ->algorithm('RS256')
                ->header('authorization')            // optional (default: authorization)
                ->scheme('Bearer')                   // optional
        )
)->respond(
    HttpResponse::response()->statusCode(200)
);

$client->when(
    HttpRequest::request()->method('POST')->path('/api/data')
        ->allOfBody([
            HttpRequest::jsonPathBody('$.name'),
            HttpRequest::regexBody('.*active.*'),
        ])
)->respond(
    HttpResponse::response()->statusCode(200)
);

use MockServer\Expectation;
use MockServer\HttpClassCallback;
use MockServer\Delay;

// Respond using a server-side ExpectationResponseCallback class
$client->upsertExpectation(
    (new Expectation())
        ->httpRequest(HttpRequest::request()->method('GET')->path('/dynamic'))
        ->httpResponseClassCallback('com.example.MyResponseCallback')
);

// Optionally add a delay / mark the connection primary
$client->upsertExpectation(
    (new Expectation())
        ->httpRequest(HttpRequest::request()->path('/delayed'))
        ->httpResponseClassCallback(
            HttpClassCallback::callback('com.example.MyResponseCallback')
                ->delay(Delay::milliseconds(250))
                ->primary(true)
        )
);

// Forward using a server-side ExpectationForwardCallback class
$client->upsertExpectation(
    (new Expectation())
        ->httpRequest(HttpRequest::request()->path('/proxy'))
        ->httpForwardClassCallback('com.example.MyForwardCallback')
);

use MockServer\VerificationTimes;

// Verify at least once
$client->verify(
    HttpRequest::request()->path('/hello'),
    VerificationTimes::atLeast(1)
);

// Verify exactly 3 times
$client->verify(
    HttpRequest::request()->method('POST')->path('/api'),
    VerificationTimes::exactly(3)
);

// Verify sequence
$client->verifySequence(
    HttpRequest::request()->path('/first'),
    HttpRequest::request()->path('/second')
);

// Retrieve recorded requests
$requests = $client->retrieveRecordedRequests(
    HttpRequest::request()->path('/api')
);

// Retrieve active expectations
$expectations = $client->retrieveActiveExpectations();

// Retrieve log messages
$logs = $client->retrieveLogMessages();

// Clear specific expectations/logs
$client->clear(HttpRequest::request()->path('/old'));
$client->clear(null, 'EXPECTATIONS');  // type: EXPECTATIONS, LOG, or ALL
$client->clearById('my-expectation-id');

// Reset everything
$client->reset();

// Check server status
$status = $client->status();  // ['ports' => [1080]]

// Bind additional ports
$client->bind(1081, 1082);

// Check if server is running
if ($client->hasStarted()) {
    echo "MockServer is ready";
}

use MockServer\LoadScenario;
use MockServer\LoadProfile;
use MockServer\LoadStage;

// Load generation registry: register scenarios (always allowed), then start
// them (LoadStage::vuHold(10, 30000),      // steady state
        LoadStage::pause(5000),            // cool down
    ))
    ->addStep(
        HttpRequest::request()->method('GET')->path('/api/item/$iteration.index'),
        Delay::milliseconds(20),
    );

$client->loadScenario($scenario);            // PUT — register (does not run)
$client->startLoadScenarios('checkout-load');// PUT /start — drive load (name or array)
$client->loadScenarios();                    // GET — list all + state
$client->getLoadScenario('checkout-load');   // GET /{name}
$client->stopLoadScenarios();                // PUT /stop — stop all (or pass names)
$client->deleteLoadScenario('checkout-load');// DELETE /{name}
$client->clearLoadScenarios();               // DELETE — remove all

// Or register-and-start in one call:
$client->runLoadScenario($scenario);

// Service-scoped HTTP chaos for a downstream host (optional TTL dead-man's switch)
$client->setServiceChaos('payments.internal:8443', [
    'errorStatus' => 503,
    'errorProbability' => 0.3,
    'latency' => ['timeUnit' => 'MILLISECONDS', 'value' => 200],
], 60000);

// SLO verdict (



use MockServer\Llm\Completion;
use MockServer\Llm\IsolationSource;
use MockServer\Llm\LlmConversationBuilder;
use MockServer\Llm\LlmFailoverBuilder;
use MockServer\Llm\LlmMockBuilder;
use MockServer\Llm\Provider;
use MockServer\Llm\Role;
use MockServer\Llm\Usage;

// Single completion mock
LlmMockBuilder::llmMock('/v1/chat/completions')
    ->withProvider(Provider::OPENAI)
    ->withModel('gpt-4o')
    ->respondingWith(
        Completion::completion()
            ->withText('Hello from a mocked model!')
            ->withStopReason('stop')
            ->withUsage(Usage::usage()->withInputTokens(12)->withOutputTokens(8))
    )
    ->applyTo($client);

// Multi-turn conversation (advances MockServer scenario state per turn),
// isolated per session by a request header
LlmConversationBuilder::conversation()
    ->withPath('/v1/chat/completions')
    ->withProvider(Provider::ANTHROPIC)
    ->isolateBy(IsolationSource::header('x-session-id'))
    ->turn()
        ->whenLatestMessageRole(Role::USER)
        ->respondingWith(Completion::completion()->withText('Hi! How can I help?'))
    ->turn()
        ->respondingWith(Completion::completion()->withText('Goodbye!'))
    ->applyTo($client);

// Provider failover: fail twice, then succeed (consecutive identical failures
// are coalesced; default JSON error bodies are supplied per status code)
LlmFailoverBuilder::llmFailover()
    ->withPath('/v1/chat/completions')
    ->withProvider(Provider::OPENAI)
    ->failWith(429)
    ->failWith(503, 2)
    ->thenRespondWith(Completion::completion()->withText('Recovered'))
    ->applyTo($client);



use MockServer\Mcp\McpMockBuilder;
use MockServer\Llm\Role;

McpMockBuilder::mcpMock('/mcp')
    ->withServerName('WeatherServer')
    ->withTool('get_weather')
        ->withDescription('Get the weather for a city')
        ->withInputSchema('{"type":"object","properties":{"city":{"type":"string"}}}')
        ->respondingWith('72F and sunny')
    ->and()
    ->withResource('file:///config.json')
        ->withName('config')
        ->withMimeType('application/json')
        ->withContent('{"debug":true}')
    ->and()
    ->withPrompt('greeting')
        ->withArgument('name', 'Who to greet', true)
        ->respondingWith(Role::ASSISTANT, 'Hello there!')
    ->and()
    ->applyTo($client);



use MockServer\A2a\A2aMockBuilder;

A2aMockBuilder::a2aMock('/a2a')
    ->withAgentName('WeatherAgent')
    ->withAgentDescription('Provides weather forecasts')
    ->withSkill('forecast')
        ->withName('Forecast')
        ->withDescription('Weather forecasting')
        ->withTag('weather')
        ->withExample('What is the weather in London?')
    ->and()
    ->onTaskSend()
        ->matchingMessage('.*weather.*')
        ->respondingWith('72F and sunny')
    ->and()
    ->withStreaming()                                  // advertise + mock message/stream (SSE)
    ->withPushNotifications('http://localhost:1234/a2a/callback')
    ->applyTo($client);

use MockServer\Testing\MockServerTestTrait;
use PHPUnit\Framework\TestCase;

final class MyTest extends TestCase
{
    use MockServerTestTrait;

    protected function setUp(): void    { $this->setUpMockServer(); }
    protected function tearDown(): void { $this->tearDownMockServer(); }

    public function testSomething(): void
    {
        // $this->mockServer is a reset MockServerClient ready to use
        $this->mockServer->reset();
    }
}