@@ -81,7 +81,29 @@ $embeddings = new FakeEmbeddingsProvider(dimensions: 1536);
8181$embeddings = FakeEmbeddingsProvider::make();
8282```
8383
84- ### 4. FakeMiddleware
84+ ### 4. FakeMcpTransport
85+
86+ For testing MCP (Model Context Protocol) integrations without a real MCP server.
87+
88+ ``` php
89+ use NeuronAI\Testing\FakeMcpTransport;
90+
91+ // Queue predetermined responses
92+ $transport = new FakeMcpTransport(
93+ ['result' => ['tools' => [['name' => 'search', 'description' => 'Search the web']]]],
94+ ['result' => ['content' => [['type' => 'text', 'text' => 'Search results...']]]],
95+ );
96+
97+ // Or add responses later
98+ $transport->addResponses(['result' => ['content' => 'More data']]);
99+ ```
100+
101+ ** Key Features:**
102+ - Responses returned sequentially from queue via ` receive() `
103+ - Records all sent/received data for assertion
104+ - Fluent MCP-specific assertions (` assertInitialized ` , ` assertToolCalled ` , etc.)
105+
106+ ### 5. FakeMiddleware
85107
86108For testing workflow middleware behavior.
87109
@@ -434,6 +456,58 @@ class MyInterruptTest extends TestCase
434456}
435457```
436458
459+ ### Testing MCP Integrations
460+
461+ Use ` FakeMcpTransport ` to test code that interacts with MCP servers without running a real server.
462+
463+ ``` php
464+ use NeuronAI\Testing\FakeMcpTransport;
465+
466+ class McpIntegrationTest extends TestCase
467+ {
468+ public function test_mcp_initialization_handshake(): void
469+ {
470+ $transport = new FakeMcpTransport(
471+ ['result' => ['capabilities' => [], 'serverInfo' => ['name' => 'test-server']]],
472+ ['result' => []],
473+ );
474+
475+ $transport->connect();
476+
477+ // Simulate initialization handshake
478+ $transport->send(['method' => 'initialize', 'params' => ['capabilities' => []]]);
479+ $transport->receive(); // consume capabilities response
480+
481+ $transport->send(['method' => 'notifications/initialized']);
482+ $transport->receive(); // consume ack
483+
484+ $transport->assertInitialized();
485+ $transport->assertConnected();
486+ }
487+
488+ public function test_mcp_tool_call(): void
489+ {
490+ $transport = new FakeMcpTransport(
491+ ['result' => ['tools' => [['name' => 'search', 'description' => 'Search']]]],
492+ ['result' => ['content' => [['type' => 'text', 'text' => 'Found 3 results']]]],
493+ );
494+
495+ $transport->connect();
496+
497+ $transport->send(['method' => 'tools/list', 'params' => []]);
498+ $transport->receive();
499+
500+ $transport->send(['method' => 'tools/call', 'params' => ['name' => 'search', 'arguments' => ['query' => 'test']]]);
501+ $transport->receive();
502+
503+ $transport->assertToolsListCalled();
504+ $transport->assertToolCalled('search');
505+ $transport->assertSendCount(2);
506+ $transport->assertReceiveCount(2);
507+ }
508+ }
509+ ```
510+
437511## Assertion Reference
438512
439513### FakeAIProvider Assertions
@@ -512,6 +586,35 @@ $middleware->assertCallCount(6);
512586$middleware->assertNotCalled();
513587```
514588
589+ ### FakeMcpTransport Assertions
590+
591+ ``` php
592+ // Verify connection state
593+ $transport->assertConnected();
594+ $transport->assertDisconnected();
595+
596+ // Verify send/receive counts
597+ $transport->assertSendCount(3);
598+ $transport->assertReceiveCount(3);
599+ $transport->assertNothingSent();
600+ $transport->assertNothingReceived();
601+
602+ // Verify specific MCP methods
603+ $transport->assertMethodSent('initialize', 1);
604+ $transport->assertMethodReceived('initialize', 1);
605+
606+ // Convenience assertions for common MCP patterns
607+ $transport->assertInitialized(); // initialize + notifications/initialized
608+ $transport->assertToolsListCalled(1); // tools/list sent N times
609+ $transport->assertToolCalled('search', 2); // tools/call with specific tool name
610+
611+ // Custom assertion with callback
612+ $transport->assertSent(function (array $data): bool {
613+ return ($data['method'] ?? null) === 'tools/call'
614+ && ($data['params']['name'] ?? null) === 'search';
615+ });
616+ ```
617+
515618## Testing Multiple Turns
516619
517620``` php
0 commit comments