dotnet-test-writer

Writes xUnit integration tests for .NET 8 minimal APIs using NSubstitute and SQLite-backed test factories.

Updated May 21, 2026
One-click install
npx skills add https://github.com/Collins1892/radar-practice --skill dotnet-test-writer-collins1892
Or copy as Structured Prompt for Agent
Please help me install this Agent Skill.
Skill: dotnet-test-writer
Source: https://github.com/Collins1892/radar-practice/tree/main/.claude/skills/dotnet-test-writer
Command: npx skills add https://github.com/Collins1892/radar-practice --skill dotnet-test-writer-collins1892

SYSTEM DOCUMENTATION & REQUIREMENTS

What problem does it solve? Writing consistent integration tests across multiple .NET 8 minimal API projects requires knowing each API's endpoints, validation rules, DTO shapes, soft-delete behavior, and test infrastructure conventions. This Skill encodes all of that so every generated test follows the same patterns and actually passes. ## Core Features & Use Cases - Convention-driven test generation: Produces one [Fact] at a time following the <HttpVerb>_<Scenario>_<ExpectedResult> naming convention, Arrange/Act/Assert comments, and per-API boilerplate (test class structure, private response records, JsonOptions with JsonStringEnumConverter). - Mocking guidance: Decides between CreateDefaultClient() (real in-memory SQLite persistence) and CreateClientWithRepo(mock) (NSubstitute override) based on the test goal, including exception paths via .Throws(...) and raw-JSON StringContent for invalid enum values. - Endpoint reference: Documents every endpoint, status code, and exact validation error message for ItemsApi, IncidentsApi, and AuditsApi, including soft-delete (RecordStatus) rules and pagination/filter/sort behavior. - Use Case: Ask for a test that verifies soft-deleted incidents return 404 on GET by id, and receive a complete [Fact] that compiles against the existing test project, followed by running dotnet test IncidentsApi.Tests/IncidentsApi.Tests.csproj to confirm the suite passes. ## Quick Start Ask the agent to write an integration test for a specific endpoint scenario, such as adding a test that POST /incidents with a blank title returns 400 with the expected error message.

Frequently Asked Questions about dotnet-test-writer

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I write integration tests for .NET 8 minimal APIs?

Use WebApplicationFactory with xUnit's IClassFixture to spin up the API in-memory, then issue HttpClient requests against endpoints. This project uses a custom TestWebApplicationFactory backed by a kept-open in-memory SQLite connection, with one [Fact] per scenario and Arrange/Act/Assert comments.

When should I mock the repository versus use real persistence in API tests?

Use a mocked repository (via NSubstitute and a singleton override) for controlled lists, 500 exception paths, and 404 scenarios. Use the real in-memory SQLite database for round-trip persistence tests like POST-then-GET, PUT updates, filter/sort/pagination, and soft-delete flows.

How do I test invalid enum values in ASP.NET Core POST requests?

Out-of-range enum ints cannot be produced by PostAsJsonAsync with a typed enum, so send raw JSON using StringContent with the invalid numeric value (for example severity 99). For query parameters, pass the invalid int directly in the URL such as ?severity=99.

Does NSubstitute support throwing exceptions from mocked methods?

Yes, NSubstitute supports exception simulation via the .Throws(...) extension in the NSubstitute.ExceptionExtensions namespace, for example repo.Add(Arg.Any<Incident>()).Throws(new InvalidOperationException(...)). Only include that using directive in test classes that actually have .Throws tests.

Why do my integration tests interfere with each other when sharing a fixture?

IClassFixture shares one TestWebApplicationFactory and its in-memory SQLite database across all [Fact]s in the class, so data persists between tests in that class. Tests asserting empty or exact-count state should use a mocked repository client to own their data completely.

How are soft-deleted records handled in API tests?

Soft delete sets RecordStatus to Deleted, which reads and updates exclude, so a second DELETE returns 404 rather than 204. RecordStatus never appears on wire DTOs, and tests can verify this by POSTing raw JSON containing recordStatus and asserting it is absent from the response.