presentation-integration-tests
Skill1 starsChanged 6 days agoMITView on GitHub
How this MCP server is tested end to end - the ModelContextProtocolApplication host, BaseToolTests with a real MCP client over HTTP, calling tools, reading resources and getting prompts, asserting error results and protocol errors, and testing with authentication on. Use when writing or fixing a test in tests/Presentation.Tests.Integration.
In this repository40 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- add-a-use-caseSkill
- api-conventionsSkill
- branches-and-pull-requestsSkill
- cancellationSkill
- ci-for-your-solutionSkill
- ci-pipelineSkill
- clean-architecture-layersSkill
- configuration-and-environmentsSkill
- coverageSkill
- csharp-house-styleSkill
- data-access-ef-coreSkill
- database-migrationsSkill
- docker-and-composeSkill
- docs-and-voiceSkill
- errors-and-exceptionsSkill
- expose-a-use-caseSkill
- family-syncSkill
- health-checksSkill
- integration-testsSkill
- json-serializationSkill
- mapping-with-mapperlySkill
- mcp-inspectorSkill
- mediatorSkill
- optional-token-authSkill
- packages-and-dependenciesSkill
- pagingSkill
- releasesSkill
- sample-dataSkill
- security-findingsSkill
- serilogSkill
- telemetrySkill
- template-authoringSkill
- test-designSkill
- time-providerSkill
- unit-testsSkill
- validationSkill
- writing-a-skillSkill
- xml-docs-and-openapiSkill
The file
We split this skill into the rules it gives an agent
1 rule. About 0 are common, 1 is distinctive, and 0 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈1
Distinctive · estimate
This author's own choices. Worth a look.
0
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 63
Call tool methods directly in an integration test.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Presentation integration tests (MCP)
The rule
tests/Presentation.Tests.Integration talks to the whole server the way a real client does. ModelContextProtocolApplication (a WebApplicationFactory<Program>) starts the server with the local environment, its own shared-cache in-memory SQLite database and the sample data on. BaseToolTests connects an McpClient to it over the streamable HTTP transport before each test and disposes both after.
| Helper | Use it to |
this.Client | Any MCP call: ListToolsAsync, ReadResourceAsync, GetPromptAsync, CompleteAsync |
CallAsync<T>(name, arguments) | Call a tool, check it didn't return an error, and read its result as T |
CallForErrorAsync(name, arguments) | Call a tool that should fail, check IsError, and return the message |
ModelContextProtocolApplication(environment, settings, configureServices) | Start a server with other settings or services, such as authentication on |
Results are read with Deserialize<T>(), which uses the server's own McpSerializer.Options (json-serialization).
Steps
- Tool, resource and prompt tests inherit
BaseToolTests. Put them inTools/,Resources/orPrompts/. - Find the rows you need through the server (search, then pick one with the property you need), not by hard-coded ids. Sample data ids are random.
- For each tool, test the success paths and each error result, asserting the message the model will read (
test-design). - For resources and prompts, assert the
McpProtocolException.ErrorCode(ResourceNotFound,InvalidParams) and its message. - A tool's name, title and annotations are checked in
ToolListTests; add a row for a new tool. - In a solution with authentication, tests that need it create their own
ModelContextProtocolApplicationwithAuthentication:*settings and a test signing key, and use a plainHttpClientor a client with a bearer token. SeeAuthentication/AuthenticationTests.cs.
Example
// tests/Presentation.Tests.Integration/Tools/BaseToolTests.cs
protected async Task<T> CallAsync<T>(string name, Dictionary<string, object?>? arguments = null)
{
var result = await this.Client.CallToolAsync(name, arguments);
result.IsError.ShouldNotBe(true, result.Content.OfType<TextContentBlock>().FirstOrDefault()?.Text);
return result.Content.OfType<TextContentBlock>().First().Text.Deserialize<T>();
}// tests/Presentation.Tests.Integration/Resources/ResourceTests.cs
[Fact]
public async Task ReadMovie_WithUnknownId_ShouldThrow_ResourceNotFound()
{
// Act
var exception = await Should.ThrowAsync<McpProtocolException>(() => this.Client.ReadResourceAsync($"movies://{Guid.NewGuid()}").AsTask());
// Assert
exception.ErrorCode.ShouldBe(McpErrorCode.ResourceNotFound);
exception.Message.ShouldContain("The Movie with the supplied id was not found.");
}Don't
- Share one server across test classes. Each test gets its own server and database.
- Call tool methods directly in an integration test. That's what the unit tests do.
- Build your own
JsonSerializerOptionsin a test. - Edit appsettings files for a test. Pass
settings. - Assume a result order the tool doesn't promise.
Check
dotnet test tests/Presentation.Tests.IntegrationDoes it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

