Skip to content

Commit 03efee0

Browse files
committed
refactor: split MockMcpTransport into client and server implementations
- Rename MockMcpTransport to MockMcpClientTransport in mcp/src/test - Create new MockMcpServerTransport implementation - Add MockMcpServerTransportProvider for server tests - Mark MockMcpTransport in mcp-test module as deprecated - Update all test classes to use the new implementations Signed-off-by: Christian Tzolov <[email protected]>
1 parent 315783f commit 03efee0

File tree

8 files changed

+260
-126
lines changed

8 files changed

+260
-126
lines changed

mcp-test/src/main/java/io/modelcontextprotocol/MockMcpTransport.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,10 @@
2222
/**
2323
* A mock implementation of the {@link McpClientTransport} and {@link McpServerTransport}
2424
* interfaces.
25+
*
26+
* @deprecated not used. to be removed in the future.
2527
*/
28+
@Deprecated
2629
public class MockMcpTransport implements McpClientTransport, McpServerTransport {
2730

2831
private final Sinks.Many<McpSchema.JSONRPCMessage> inbound = Sinks.many().unicast().onBackpressureBuffer();

mcp/src/test/java/io/modelcontextprotocol/MockMcpTransport.java renamed to mcp/src/test/java/io/modelcontextprotocol/MockMcpClientTransport.java

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,28 +15,26 @@
1515
import io.modelcontextprotocol.spec.McpSchema;
1616
import io.modelcontextprotocol.spec.McpSchema.JSONRPCNotification;
1717
import io.modelcontextprotocol.spec.McpSchema.JSONRPCRequest;
18-
import io.modelcontextprotocol.spec.McpServerTransport;
1918
import reactor.core.publisher.Mono;
2019
import reactor.core.publisher.Sinks;
2120

2221
/**
23-
* A mock implementation of the {@link McpClientTransport} and {@link McpServerTransport}
24-
* interfaces.
22+
* A mock implementation of the {@link McpClientTransport} interfaces.
2523
*/
26-
public class MockMcpTransport implements McpClientTransport, McpServerTransport {
24+
public class MockMcpClientTransport implements McpClientTransport {
2725

2826
private final Sinks.Many<McpSchema.JSONRPCMessage> inbound = Sinks.many().unicast().onBackpressureBuffer();
2927

3028
private final List<McpSchema.JSONRPCMessage> sent = new ArrayList<>();
3129

32-
private final BiConsumer<MockMcpTransport, McpSchema.JSONRPCMessage> interceptor;
30+
private final BiConsumer<MockMcpClientTransport, McpSchema.JSONRPCMessage> interceptor;
3331

34-
public MockMcpTransport() {
32+
public MockMcpClientTransport() {
3533
this((t, msg) -> {
3634
});
3735
}
3836

39-
public MockMcpTransport(BiConsumer<MockMcpTransport, McpSchema.JSONRPCMessage> interceptor) {
37+
public MockMcpClientTransport(BiConsumer<MockMcpClientTransport, McpSchema.JSONRPCMessage> interceptor) {
4038
this.interceptor = interceptor;
4139
}
4240

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/*
2+
* Copyright 2024-2024 the original author or authors.
3+
*/
4+
5+
package io.modelcontextprotocol;
6+
7+
import java.util.ArrayList;
8+
import java.util.List;
9+
import java.util.function.BiConsumer;
10+
11+
import com.fasterxml.jackson.core.type.TypeReference;
12+
import com.fasterxml.jackson.databind.ObjectMapper;
13+
import io.modelcontextprotocol.spec.McpSchema;
14+
import io.modelcontextprotocol.spec.McpSchema.JSONRPCNotification;
15+
import io.modelcontextprotocol.spec.McpSchema.JSONRPCRequest;
16+
import io.modelcontextprotocol.spec.McpServerTransport;
17+
import reactor.core.publisher.Mono;
18+
19+
/**
20+
* A mock implementation of the {@link McpServerTransport} interfaces.
21+
*/
22+
public class MockMcpServerTransport implements McpServerTransport {
23+
24+
private final List<McpSchema.JSONRPCMessage> sent = new ArrayList<>();
25+
26+
private final BiConsumer<MockMcpServerTransport, McpSchema.JSONRPCMessage> interceptor;
27+
28+
public MockMcpServerTransport() {
29+
this((t, msg) -> {
30+
});
31+
}
32+
33+
public MockMcpServerTransport(BiConsumer<MockMcpServerTransport, McpSchema.JSONRPCMessage> interceptor) {
34+
this.interceptor = interceptor;
35+
}
36+
37+
@Override
38+
public Mono<Void> sendMessage(McpSchema.JSONRPCMessage message) {
39+
sent.add(message);
40+
interceptor.accept(this, message);
41+
return Mono.empty();
42+
}
43+
44+
public McpSchema.JSONRPCRequest getLastSentMessageAsRequest() {
45+
return (JSONRPCRequest) getLastSentMessage();
46+
}
47+
48+
public McpSchema.JSONRPCNotification getLastSentMessageAsNotification() {
49+
return (JSONRPCNotification) getLastSentMessage();
50+
}
51+
52+
public McpSchema.JSONRPCMessage getLastSentMessage() {
53+
return !sent.isEmpty() ? sent.get(sent.size() - 1) : null;
54+
}
55+
56+
@Override
57+
public Mono<Void> closeGracefully() {
58+
return Mono.defer(() -> {
59+
return Mono.empty();
60+
});
61+
}
62+
63+
@Override
64+
public <T> T unmarshalFrom(Object data, TypeReference<T> typeRef) {
65+
return new ObjectMapper().convertValue(data, typeRef);
66+
}
67+
68+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*
2+
* Copyright 2025 - 2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.modelcontextprotocol;
17+
18+
import java.util.Map;
19+
20+
import io.modelcontextprotocol.spec.McpSchema;
21+
import io.modelcontextprotocol.spec.McpServerSession;
22+
import io.modelcontextprotocol.spec.McpServerSession.Factory;
23+
import io.modelcontextprotocol.spec.McpServerTransportProvider;
24+
import reactor.core.publisher.Mono;
25+
26+
/**
27+
* @author Christian Tzolov
28+
*/
29+
public class MockMcpServerTransportProvider implements McpServerTransportProvider {
30+
31+
private McpServerSession session;
32+
33+
private final MockMcpServerTransport transport;
34+
35+
public MockMcpServerTransportProvider(MockMcpServerTransport transport) {
36+
this.transport = transport;
37+
}
38+
39+
public MockMcpServerTransport getTransport() {
40+
return transport;
41+
}
42+
43+
@Override
44+
public void setSessionFactory(Factory sessionFactory) {
45+
46+
session = sessionFactory.create(transport);
47+
}
48+
49+
@Override
50+
public Mono<Void> notifyClients(String method, Map<String, Object> params) {
51+
return session.sendNotification(method, params);
52+
}
53+
54+
@Override
55+
public Mono<Void> closeGracefully() {
56+
return session.closeGracefully();
57+
}
58+
59+
public void simulateIncomingMessage(McpSchema.JSONRPCMessage message) {
60+
session.handle(message).subscribe();
61+
}
62+
63+
}

mcp/src/test/java/io/modelcontextprotocol/client/McpAsyncClientResponseHandlerTests.java

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
import com.fasterxml.jackson.core.JsonProcessingException;
1313
import com.fasterxml.jackson.core.type.TypeReference;
1414
import com.fasterxml.jackson.databind.ObjectMapper;
15-
import io.modelcontextprotocol.MockMcpTransport;
15+
import io.modelcontextprotocol.MockMcpClientTransport;
1616
import io.modelcontextprotocol.spec.McpError;
1717
import io.modelcontextprotocol.spec.McpSchema;
1818
import io.modelcontextprotocol.spec.McpSchema.ClientCapabilities;
@@ -34,16 +34,16 @@ class McpAsyncClientResponseHandlerTests {
3434
.resources(true, true) // Enable both resources and resource templates
3535
.build();
3636

37-
private static MockMcpTransport initializationEnabledTransport() {
37+
private static MockMcpClientTransport initializationEnabledTransport() {
3838
return initializationEnabledTransport(SERVER_CAPABILITIES, SERVER_INFO);
3939
}
4040

41-
private static MockMcpTransport initializationEnabledTransport(McpSchema.ServerCapabilities mockServerCapabilities,
42-
McpSchema.Implementation mockServerInfo) {
41+
private static MockMcpClientTransport initializationEnabledTransport(
42+
McpSchema.ServerCapabilities mockServerCapabilities, McpSchema.Implementation mockServerInfo) {
4343
McpSchema.InitializeResult mockInitResult = new McpSchema.InitializeResult(McpSchema.LATEST_PROTOCOL_VERSION,
4444
mockServerCapabilities, mockServerInfo, "Test instructions");
4545

46-
return new MockMcpTransport((t, message) -> {
46+
return new MockMcpClientTransport((t, message) -> {
4747
if (message instanceof McpSchema.JSONRPCRequest r && METHOD_INITIALIZE.equals(r.method())) {
4848
McpSchema.JSONRPCResponse initResponse = new McpSchema.JSONRPCResponse(McpSchema.JSONRPC_VERSION,
4949
r.id(), mockInitResult, null);
@@ -59,7 +59,7 @@ void testSuccessfulInitialization() {
5959
.tools(false)
6060
.resources(true, true) // Enable both resources and resource templates
6161
.build();
62-
MockMcpTransport transport = initializationEnabledTransport(serverCapabilities, serverInfo);
62+
MockMcpClientTransport transport = initializationEnabledTransport(serverCapabilities, serverInfo);
6363
McpAsyncClient asyncMcpClient = McpClient.async(transport).build();
6464

6565
// Verify client is not initialized initially
@@ -91,7 +91,7 @@ void testSuccessfulInitialization() {
9191

9292
@Test
9393
void testToolsChangeNotificationHandling() throws JsonProcessingException {
94-
MockMcpTransport transport = initializationEnabledTransport();
94+
MockMcpClientTransport transport = initializationEnabledTransport();
9595

9696
// Create a list to store received tools for verification
9797
List<McpSchema.Tool> receivedTools = new ArrayList<>();
@@ -134,7 +134,7 @@ void testToolsChangeNotificationHandling() throws JsonProcessingException {
134134

135135
@Test
136136
void testRootsListRequestHandling() {
137-
MockMcpTransport transport = initializationEnabledTransport();
137+
MockMcpClientTransport transport = initializationEnabledTransport();
138138

139139
McpAsyncClient asyncMcpClient = McpClient.async(transport)
140140
.roots(new Root("file:///test/path", "test-root"))
@@ -162,7 +162,7 @@ void testRootsListRequestHandling() {
162162

163163
@Test
164164
void testResourcesChangeNotificationHandling() {
165-
MockMcpTransport transport = initializationEnabledTransport();
165+
MockMcpClientTransport transport = initializationEnabledTransport();
166166

167167
// Create a list to store received resources for verification
168168
List<McpSchema.Resource> receivedResources = new ArrayList<>();
@@ -208,7 +208,7 @@ void testResourcesChangeNotificationHandling() {
208208

209209
@Test
210210
void testPromptsChangeNotificationHandling() {
211-
MockMcpTransport transport = initializationEnabledTransport();
211+
MockMcpClientTransport transport = initializationEnabledTransport();
212212

213213
// Create a list to store received prompts for verification
214214
List<McpSchema.Prompt> receivedPrompts = new ArrayList<>();
@@ -252,7 +252,7 @@ void testPromptsChangeNotificationHandling() {
252252

253253
@Test
254254
void testSamplingCreateMessageRequestHandling() {
255-
MockMcpTransport transport = initializationEnabledTransport();
255+
MockMcpClientTransport transport = initializationEnabledTransport();
256256

257257
// Create a test sampling handler that echoes back the input
258258
Function<McpSchema.CreateMessageRequest, Mono<McpSchema.CreateMessageResult>> samplingHandler = request -> {
@@ -306,7 +306,7 @@ void testSamplingCreateMessageRequestHandling() {
306306

307307
@Test
308308
void testSamplingCreateMessageRequestHandlingWithoutCapability() {
309-
MockMcpTransport transport = initializationEnabledTransport();
309+
MockMcpClientTransport transport = initializationEnabledTransport();
310310

311311
// Create client without sampling capability
312312
McpAsyncClient asyncMcpClient = McpClient.async(transport)
@@ -340,7 +340,7 @@ void testSamplingCreateMessageRequestHandlingWithoutCapability() {
340340

341341
@Test
342342
void testSamplingCreateMessageRequestHandlingWithNullHandler() {
343-
MockMcpTransport transport = new MockMcpTransport();
343+
MockMcpClientTransport transport = new MockMcpClientTransport();
344344

345345
// Create client with sampling capability but null handler
346346
assertThatThrownBy(

mcp/src/test/java/io/modelcontextprotocol/client/McpClientProtocolVersionTests.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import java.time.Duration;
88
import java.util.List;
99

10-
import io.modelcontextprotocol.MockMcpTransport;
10+
import io.modelcontextprotocol.MockMcpClientTransport;
1111
import io.modelcontextprotocol.spec.McpError;
1212
import io.modelcontextprotocol.spec.McpSchema;
1313
import io.modelcontextprotocol.spec.McpSchema.InitializeResult;
@@ -28,7 +28,7 @@ class McpClientProtocolVersionTests {
2828

2929
@Test
3030
void shouldUseLatestVersionByDefault() {
31-
MockMcpTransport transport = new MockMcpTransport();
31+
MockMcpClientTransport transport = new MockMcpClientTransport();
3232
McpAsyncClient client = McpClient.async(transport)
3333
.clientInfo(CLIENT_INFO)
3434
.requestTimeout(REQUEST_TIMEOUT)
@@ -61,7 +61,7 @@ void shouldUseLatestVersionByDefault() {
6161
@Test
6262
void shouldNegotiateSpecificVersion() {
6363
String oldVersion = "0.1.0";
64-
MockMcpTransport transport = new MockMcpTransport();
64+
MockMcpClientTransport transport = new MockMcpClientTransport();
6565
McpAsyncClient client = McpClient.async(transport)
6666
.clientInfo(CLIENT_INFO)
6767
.requestTimeout(REQUEST_TIMEOUT)
@@ -94,7 +94,7 @@ void shouldNegotiateSpecificVersion() {
9494
@Test
9595
void shouldFailForUnsupportedVersion() {
9696
String unsupportedVersion = "999.999.999";
97-
MockMcpTransport transport = new MockMcpTransport();
97+
MockMcpClientTransport transport = new MockMcpClientTransport();
9898
McpAsyncClient client = McpClient.async(transport)
9999
.clientInfo(CLIENT_INFO)
100100
.requestTimeout(REQUEST_TIMEOUT)
@@ -124,7 +124,7 @@ void shouldUseHighestVersionWhenMultipleSupported() {
124124
String middleVersion = "0.2.0";
125125
String latestVersion = McpSchema.LATEST_PROTOCOL_VERSION;
126126

127-
MockMcpTransport transport = new MockMcpTransport();
127+
MockMcpClientTransport transport = new MockMcpClientTransport();
128128
McpAsyncClient client = McpClient.async(transport)
129129
.clientInfo(CLIENT_INFO)
130130
.requestTimeout(REQUEST_TIMEOUT)

0 commit comments

Comments
 (0)