testing-dotnet
| Type | Skill |
| Plugin | awl-testing · v0.0.27 |
| Invoke | /awl-testing:testing-dotnet |
| Tools | Read, Write, Edit, Bash, Glob, Grep |
| Source | plugins/awl-testing/skills/testing-dotnet/SKILL.md |
When Claude uses it
Abschnitt betitelt „When Claude uses it“Writes and debugs .NET tests using xUnit, Moq, FluentAssertions, and Testcontainers. Use when “write dotnet tests”, “xunit test”, “mock with moq”, “test c# code”, “fluentassertions”, “testcontainers”, “integration test c#”, “api test dotnet”, “fix dotnet test”, “debug test failure”, “test fixture setup”, “theory test”, “fact test”.
Trigger phrases: write dotnet tests · xunit test · mock with moq · test c# code · fluentassertions · testcontainers · integration test c# · api test dotnet · fix dotnet test · debug test failure · test fixture setup · theory test · fact test
Definition
Abschnitt betitelt „Definition“Quick Start
Abschnitt betitelt „Quick Start“[Fact]public void CreateUser_WithoutEmail_ShouldThrow(){ // Arrange var service = new UserService();
// Act Action act = () => service.CreateUser(new UserData { Name = "Alice" });
// Assert act.Should().Throw<ArgumentException>().WithMessage("*email*");}Run tests:
dotnet testdotnet test --filter "FullyQualifiedName~UserService"When to Use
Abschnitt betitelt „When to Use“| Task | This Skill Helps With |
|---|---|
| Unit tests | Testing isolated components with mocks |
| Integration tests | Testing with databases, EF Core |
| API tests | Testing ASP.NET Core endpoints |
| Test failures | Debugging red tests, fixing assertions |
| Test setup | Fixtures, lifecycle, IAsyncLifetime |
Naming Conventions
Abschnitt betitelt „Naming Conventions“Classes: <TypeUnderTest>Tests (e.g., UserServiceTests)
Methods: <Method>_<State>_<Expected> (e.g., CreateUser_WithoutEmail_ShouldThrow)
Projects: Tests.Unit, Tests.Integration, Tests.Api
Core Patterns
Abschnitt betitelt „Core Patterns“Unit Test with Moq
Abschnitt betitelt „Unit Test with Moq“[Fact]public async Task GetUserById_ExistingUser_ReturnsUser(){ // Arrange var mockRepo = new Mock<IUserRepository>(); mockRepo.Setup(r => r.GetByIdAsync(1)) .ReturnsAsync(new User { Id = 1, Name = "John" }); var service = new UserService(mockRepo.Object);
// Act var user = await service.GetUserByIdAsync(1);
// Assert user.Should().NotBeNull(); user.Name.Should().Be("John"); mockRepo.Verify(r => r.GetByIdAsync(1), Times.Once);}Parameterized Test
Abschnitt betitelt „Parameterized Test“[Theory][InlineData(2, 3, 5)][InlineData(-1, 1, 0)][InlineData(0, 0, 0)]public void Add_ReturnsExpectedResult(int a, int b, int expected){ // Arrange var calc = new Calculator();
// Act var result = calc.Add(a, b);
// Assert result.Should().Be(expected);}Exception Testing
Abschnitt betitelt „Exception Testing“[Fact]public void Process_NullInput_ThrowsArgumentNull(){ // Arrange var service = new MyService();
// Act Action act = () => service.ProcessData(null);
// Assert act.Should().Throw<ArgumentNullException>().WithMessage("*data*");}Async Testing
Abschnitt betitelt „Async Testing“[Fact]public async Task ProcessAsync_ValidInput_Succeeds(){ // Arrange var service = new MyService();
// Act var result = await service.ProcessAsync(validData);
// Assert result.Should().NotBeNull();}Setup & Teardown
Abschnitt betitelt „Setup & Teardown“Per-Test (Constructor/Dispose)
Abschnitt betitelt „Per-Test (Constructor/Dispose)“public class UserServiceTests : IDisposable{ private readonly UserService _service; private readonly Mock<IUserRepository> _mockRepo;
public UserServiceTests() { _mockRepo = new Mock<IUserRepository>(); _service = new UserService(_mockRepo.Object); }
public void Dispose() => _service?.Dispose();}Async Lifecycle
Abschnitt betitelt „Async Lifecycle“public class DatabaseTests : IAsyncLifetime{ private TestDatabase _db;
public async Task InitializeAsync() { _db = new TestDatabase(); await _db.ConnectAsync(); }
public async Task DisposeAsync() => await _db.CleanupAsync();}Shared Fixture
Abschnitt betitelt „Shared Fixture“public class DatabaseFixture : IAsyncLifetime{ public DbContext DbContext { get; private set; }
public async Task InitializeAsync() { DbContext = await CreateDbContextAsync(); await DbContext.Database.MigrateAsync(); }
public async Task DisposeAsync() => await DbContext.DisposeAsync();}
public class MyTests : IClassFixture<DatabaseFixture>{ private readonly DatabaseFixture _fixture; public MyTests(DatabaseFixture fixture) => _fixture = fixture;}Common Assertions (FluentAssertions)
Abschnitt betitelt „Common Assertions (FluentAssertions)“result.Should().Be(expected);result.Should().NotBeNull();list.Should().NotBeEmpty();list.Should().HaveCount(3);list.Should().Contain(item);list.Should().OnlyContain(x => x.IsActive);str.Should().StartWith("Hello");str.Should().Contain("world");Troubleshooting
Abschnitt betitelt „Troubleshooting“Test Not Running
Abschnitt betitelt „Test Not Running“# Check if discovereddotnet test --list-tests
# Rebuilddotnet clean && dotnet build
# Check filterdotnet test --filter "FullyQualifiedName~ClassName"Async Test Hangs
Abschnitt betitelt „Async Test Hangs“// BAD: Blocks threadvar result = service.GetAsync().Result;
// GOOD: Await properlyvar result = await service.GetAsync();Mock Not Returning Value
Abschnitt betitelt „Mock Not Returning Value“// BAD: Wrong setupmockRepo.Setup(r => r.GetById(1));
// GOOD: Return valuemockRepo.Setup(r => r.GetById(1)).Returns(user);mockRepo.Setup(r => r.GetByIdAsync(1)).ReturnsAsync(user);FluentAssertions Not Found
Abschnitt betitelt „FluentAssertions Not Found“dotnet add package FluentAssertionsThen add using FluentAssertions; to test file.
Best Practices
Abschnitt betitelt „Best Practices“- AAA Pattern - Always Arrange-Act-Assert with comments
- One assertion concept - Test one behavior per method
- Descriptive names - Method name explains the scenario
- Independent tests - No shared state, no order dependency
- Async all the way - Never
.Resultor.Wait() - FluentAssertions - More readable than xUnit assertions
- Fakes over mocks - When simpler implementations work
Running Tests
Abschnitt betitelt „Running Tests“# All testsdotnet test
# Specific projectdotnet test Tests.Unit/Tests.Unit.csproj
# Filter by namedotnet test --filter "FullyQualifiedName~UserService"
# With coveragedotnet test /p:CollectCoverage=true
# Verbose outputdotnet test --logger:"console;verbosity=detailed"References
Abschnitt betitelt „References“For advanced patterns and complete examples:
- UNIT_TESTING.md - xUnit features, fixtures, parameterized tests
- INTEGRATION_TESTING.md - Database testing, EF Core patterns
- API_TESTING.md - WebApplicationFactory, endpoint testing
- TESTCONTAINERS.md - Docker containers for tests

