Use when implementing ASP.NET Core + EF Core features or bugfixes with xUnit tests, before writing implementation code.
View on GitHubplugins/saurun/skills/dotnet-tdd/SKILL.md
February 5, 2026
Select agents to install to:
npx add-skill https://github.com/fiatkongen/saurun-marketplace/blob/main/plugins/saurun/skills/dotnet-tdd/SKILL.md -a claude-code --skill dotnet-tddInstallation paths:
.claude/skills/dotnet-tdd/# .NET Test-Driven Development (TDD) ## Overview Write the test first. Watch it fail. Write minimal code to pass. **Core principle:** If you didn't watch the test fail, you don't know if it tests the right thing. **Violating the letter of the rules is violating the spirit of the rules.** ## Quick Reference | Step | Action | Verify | |------|--------|--------| | RED | Write one failing test | Fails for expected reason (missing feature, not typo) | | GREEN | Write minimal code to pass | This test + all others pass | | REFACTOR | Clean up, no new behavior | All tests still green | | Mock rule | Mock infrastructure only | Domain objects are real, never mocked | | Naming | `MethodName_Scenario_ExpectedBehavior` | Clear, behavioral, no `CanSet*` | | Assertions | Max 3 per test | Use `[Theory]` for parameterized cases | ## When to Use **Always:** New features, bug fixes, refactoring, behavior changes. **Exceptions (ask your human partner):** Throwaway prototypes, generated code, configuration files. Thinking "skip TDD just this once"? Stop. That's rationalization. ## The Iron Laws ``` 1. NO PRODUCTION CODE WITHOUT A FAILING TEST FIRST 2. NEVER add test-only methods to production classes 3. MOCK BOUNDARY RULE (see below) ``` Write code before the test? Delete it. Start over. **No exceptions:** - Don't keep it as "reference" - Don't "adapt" it while writing tests - Don't look at it - Delete means delete ### Mock Boundary Rule **Mock infrastructure. NEVER mock domain.** **OK to mock:** `DbContext`/repositories, `IHttpClientFactory`, `ILogger<T>`, `TimeProvider`, external API clients, message queues, file systems. **NEVER mock:** Domain entities, value objects, pure functions, domain services with no I/O. **Use NSubstitute** for all mocking. Not Moq, not FakeItEasy. ```csharp // OK: mocking infrastructure var repo = Substitute.For<IShoppingListRepository>(); repo.GetByIdAsync(listId).Returns(existingList); // NEVER: mocking domain var item = Substitute.For