Skip to content

Commit 5755349

Browse files
Copilotstephentoub
andcommitted
Round out delegating type tests with ctor, property, and method delegation validation
Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>
1 parent d6d7123 commit 5755349

3 files changed

Lines changed: 238 additions & 0 deletions

File tree

tests/ModelContextProtocol.Tests/Server/DelegatingMcpServerPromptTests.cs

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,79 @@
1+
using ModelContextProtocol.Protocol;
12
using ModelContextProtocol.Server;
3+
using Moq;
24
using System.Reflection;
35

46
namespace ModelContextProtocol.Tests.Server;
57

68
public class DelegatingMcpServerPromptTests
79
{
10+
private static JsonRpcRequest CreateTestJsonRpcRequest() => new()
11+
{
12+
Id = new RequestId("test-id"),
13+
Method = "test/method",
14+
Params = null,
15+
};
16+
17+
[Fact]
18+
public void Ctor_NullInnerPrompt_Throws()
19+
{
20+
Assert.Throws<ArgumentNullException>("innerPrompt", () => new TestDelegatingMcpServerPrompt(null!));
21+
}
22+
23+
[Fact]
24+
public void ProtocolPrompt_DelegatesToInnerPrompt()
25+
{
26+
Prompt expected = new() { Name = "test-prompt" };
27+
Mock<McpServerPrompt> mock = new();
28+
mock.Setup(p => p.ProtocolPrompt).Returns(expected);
29+
30+
TestDelegatingMcpServerPrompt delegating = new(mock.Object);
31+
32+
Assert.Same(expected, delegating.ProtocolPrompt);
33+
mock.Verify(p => p.ProtocolPrompt, Times.Once);
34+
}
35+
36+
[Fact]
37+
public void Metadata_DelegatesToInnerPrompt()
38+
{
39+
IReadOnlyList<object> expected = new object[] { "attr1", "attr2" };
40+
Mock<McpServerPrompt> mock = new();
41+
mock.Setup(p => p.Metadata).Returns(expected);
42+
43+
TestDelegatingMcpServerPrompt delegating = new(mock.Object);
44+
45+
Assert.Same(expected, delegating.Metadata);
46+
mock.Verify(p => p.Metadata, Times.Once);
47+
}
48+
49+
[Fact]
50+
public async Task GetAsync_DelegatesToInnerPrompt()
51+
{
52+
GetPromptResult expected = new() { Messages = [] };
53+
RequestContext<GetPromptRequestParams> request = new(new Mock<McpServer>().Object, CreateTestJsonRpcRequest());
54+
using CancellationTokenSource cts = new();
55+
Mock<McpServerPrompt> mock = new();
56+
mock.Setup(p => p.GetAsync(request, cts.Token)).ReturnsAsync(expected);
57+
58+
TestDelegatingMcpServerPrompt delegating = new(mock.Object);
59+
60+
GetPromptResult result = await delegating.GetAsync(request, cts.Token);
61+
62+
Assert.Same(expected, result);
63+
mock.Verify(p => p.GetAsync(request, cts.Token), Times.Once);
64+
}
65+
66+
[Fact]
67+
public void ToString_DelegatesToInnerPrompt()
68+
{
69+
Mock<McpServerPrompt> mock = new();
70+
mock.Setup(p => p.ToString()).Returns("inner-prompt-string");
71+
72+
TestDelegatingMcpServerPrompt delegating = new(mock.Object);
73+
74+
Assert.Equal("inner-prompt-string", delegating.ToString());
75+
}
76+
877
[Fact]
978
public void OverridesAllVirtualAndAbstractMembers()
1079
{
@@ -26,4 +95,6 @@ public void OverridesAllVirtualAndAbstractMembers()
2695
$"DelegatingMcpServerPrompt does not override {baseMethod.Name} from McpServerPrompt.");
2796
}
2897
}
98+
99+
private sealed class TestDelegatingMcpServerPrompt(McpServerPrompt innerPrompt) : DelegatingMcpServerPrompt(innerPrompt);
29100
}

tests/ModelContextProtocol.Tests/Server/DelegatingMcpServerResourceTests.cs

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,104 @@
1+
using ModelContextProtocol.Protocol;
12
using ModelContextProtocol.Server;
3+
using Moq;
24
using System.Reflection;
35

46
namespace ModelContextProtocol.Tests.Server;
57

68
public class DelegatingMcpServerResourceTests
79
{
10+
private static JsonRpcRequest CreateTestJsonRpcRequest() => new()
11+
{
12+
Id = new RequestId("test-id"),
13+
Method = "test/method",
14+
Params = null,
15+
};
16+
17+
[Fact]
18+
public void Ctor_NullInnerResource_Throws()
19+
{
20+
Assert.Throws<ArgumentNullException>("innerResource", () => new TestDelegatingMcpServerResource(null!));
21+
}
22+
23+
[Fact]
24+
public void ProtocolResourceTemplate_DelegatesToInnerResource()
25+
{
26+
ResourceTemplate expected = new() { Name = "test-resource", UriTemplate = "test://resource" };
27+
Mock<McpServerResource> mock = new();
28+
mock.Setup(r => r.ProtocolResourceTemplate).Returns(expected);
29+
30+
TestDelegatingMcpServerResource delegating = new(mock.Object);
31+
32+
Assert.Same(expected, delegating.ProtocolResourceTemplate);
33+
mock.Verify(r => r.ProtocolResourceTemplate, Times.Once);
34+
}
35+
36+
[Fact]
37+
public void ProtocolResource_DelegatesToInnerResource()
38+
{
39+
Resource expected = new() { Name = "test-resource", Uri = "test://resource" };
40+
Mock<McpServerResource> mock = new();
41+
mock.Setup(r => r.ProtocolResource).Returns(expected);
42+
43+
TestDelegatingMcpServerResource delegating = new(mock.Object);
44+
45+
Assert.Same(expected, delegating.ProtocolResource);
46+
mock.Verify(r => r.ProtocolResource, Times.Once);
47+
}
48+
49+
[Fact]
50+
public void Metadata_DelegatesToInnerResource()
51+
{
52+
IReadOnlyList<object> expected = new object[] { "attr1", "attr2" };
53+
Mock<McpServerResource> mock = new();
54+
mock.Setup(r => r.Metadata).Returns(expected);
55+
56+
TestDelegatingMcpServerResource delegating = new(mock.Object);
57+
58+
Assert.Same(expected, delegating.Metadata);
59+
mock.Verify(r => r.Metadata, Times.Once);
60+
}
61+
62+
[Fact]
63+
public void IsMatch_DelegatesToInnerResource()
64+
{
65+
Mock<McpServerResource> mock = new();
66+
mock.Setup(r => r.IsMatch("test://resource")).Returns(true);
67+
68+
TestDelegatingMcpServerResource delegating = new(mock.Object);
69+
70+
Assert.True(delegating.IsMatch("test://resource"));
71+
mock.Verify(r => r.IsMatch("test://resource"), Times.Once);
72+
}
73+
74+
[Fact]
75+
public async Task ReadAsync_DelegatesToInnerResource()
76+
{
77+
ReadResourceResult expected = new() { Contents = [] };
78+
RequestContext<ReadResourceRequestParams> request = new(new Mock<McpServer>().Object, CreateTestJsonRpcRequest());
79+
using CancellationTokenSource cts = new();
80+
Mock<McpServerResource> mock = new();
81+
mock.Setup(r => r.ReadAsync(request, cts.Token)).ReturnsAsync(expected);
82+
83+
TestDelegatingMcpServerResource delegating = new(mock.Object);
84+
85+
ReadResourceResult result = await delegating.ReadAsync(request, cts.Token);
86+
87+
Assert.Same(expected, result);
88+
mock.Verify(r => r.ReadAsync(request, cts.Token), Times.Once);
89+
}
90+
91+
[Fact]
92+
public void ToString_DelegatesToInnerResource()
93+
{
94+
Mock<McpServerResource> mock = new();
95+
mock.Setup(r => r.ToString()).Returns("inner-resource-string");
96+
97+
TestDelegatingMcpServerResource delegating = new(mock.Object);
98+
99+
Assert.Equal("inner-resource-string", delegating.ToString());
100+
}
101+
8102
[Fact]
9103
public void OverridesAllVirtualAndAbstractMembers()
10104
{
@@ -26,4 +120,6 @@ public void OverridesAllVirtualAndAbstractMembers()
26120
$"DelegatingMcpServerResource does not override {baseMethod.Name} from McpServerResource.");
27121
}
28122
}
123+
124+
private sealed class TestDelegatingMcpServerResource(McpServerResource innerResource) : DelegatingMcpServerResource(innerResource);
29125
}

tests/ModelContextProtocol.Tests/Server/DelegatingMcpServerToolTests.cs

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,79 @@
1+
using ModelContextProtocol.Protocol;
12
using ModelContextProtocol.Server;
3+
using Moq;
24
using System.Reflection;
35

46
namespace ModelContextProtocol.Tests.Server;
57

68
public class DelegatingMcpServerToolTests
79
{
10+
private static JsonRpcRequest CreateTestJsonRpcRequest() => new()
11+
{
12+
Id = new RequestId("test-id"),
13+
Method = "test/method",
14+
Params = null,
15+
};
16+
17+
[Fact]
18+
public void Ctor_NullInnerTool_Throws()
19+
{
20+
Assert.Throws<ArgumentNullException>("innerTool", () => new TestDelegatingMcpServerTool(null!));
21+
}
22+
23+
[Fact]
24+
public void ProtocolTool_DelegatesToInnerTool()
25+
{
26+
Tool expected = new() { Name = "test-tool" };
27+
Mock<McpServerTool> mock = new();
28+
mock.Setup(t => t.ProtocolTool).Returns(expected);
29+
30+
TestDelegatingMcpServerTool delegating = new(mock.Object);
31+
32+
Assert.Same(expected, delegating.ProtocolTool);
33+
mock.Verify(t => t.ProtocolTool, Times.Once);
34+
}
35+
36+
[Fact]
37+
public void Metadata_DelegatesToInnerTool()
38+
{
39+
IReadOnlyList<object> expected = new object[] { "attr1", "attr2" };
40+
Mock<McpServerTool> mock = new();
41+
mock.Setup(t => t.Metadata).Returns(expected);
42+
43+
TestDelegatingMcpServerTool delegating = new(mock.Object);
44+
45+
Assert.Same(expected, delegating.Metadata);
46+
mock.Verify(t => t.Metadata, Times.Once);
47+
}
48+
49+
[Fact]
50+
public async Task InvokeAsync_DelegatesToInnerTool()
51+
{
52+
CallToolResult expected = new() { Content = [] };
53+
RequestContext<CallToolRequestParams> request = new(new Mock<McpServer>().Object, CreateTestJsonRpcRequest());
54+
using CancellationTokenSource cts = new();
55+
Mock<McpServerTool> mock = new();
56+
mock.Setup(t => t.InvokeAsync(request, cts.Token)).ReturnsAsync(expected);
57+
58+
TestDelegatingMcpServerTool delegating = new(mock.Object);
59+
60+
CallToolResult result = await delegating.InvokeAsync(request, cts.Token);
61+
62+
Assert.Same(expected, result);
63+
mock.Verify(t => t.InvokeAsync(request, cts.Token), Times.Once);
64+
}
65+
66+
[Fact]
67+
public void ToString_DelegatesToInnerTool()
68+
{
69+
Mock<McpServerTool> mock = new();
70+
mock.Setup(t => t.ToString()).Returns("inner-tool-string");
71+
72+
TestDelegatingMcpServerTool delegating = new(mock.Object);
73+
74+
Assert.Equal("inner-tool-string", delegating.ToString());
75+
}
76+
877
[Fact]
978
public void OverridesAllVirtualAndAbstractMembers()
1079
{
@@ -26,4 +95,6 @@ public void OverridesAllVirtualAndAbstractMembers()
2695
$"DelegatingMcpServerTool does not override {baseMethod.Name} from McpServerTool.");
2796
}
2897
}
98+
99+
private sealed class TestDelegatingMcpServerTool(McpServerTool innerTool) : DelegatingMcpServerTool(innerTool);
29100
}

0 commit comments

Comments
 (0)