| name | dotnet-testing-setup |
| description | Setting up comprehensive test infrastructure for .NET projects with xUnit, Moq, and EF Core InMemory |
| domain | testing |
| confidence | medium |
| source | earned |
| tools | [{"name":"powershell","description":"Execute dotnet CLI commands","when":"Creating test projects, restoring packages, building, running tests"},{"name":"edit","description":"Modify .csproj and source files","when":"Configuring test project dependencies and target frameworks"}] |
Context
When setting up test infrastructure for a .NET project that uses Entity Framework Core, MAUI, or other platform-specific frameworks. This skill covers project creation, dependency selection, and test helper patterns.
Patterns
1. Test Project Setup
Create xUnit test project:
dotnet new xunit -n {ProjectName}.Tests -o {ProjectName}.Tests
Match target framework to main project:
2. Test Dependencies
Standard .NET testing stack:
<PackageReference Include="xunit" Version="2.9.3" />
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.4" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
<PackageReference Include="Moq" Version="4.20.72" />
<PackageReference Include="FluentAssertions" Version="7.0.0" />
For EF Core testing:
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="{match-main-version}" />
For HTTP client testing:
<PackageReference Include="RichardSzalay.MockHttp" Version="7.0.0" />
Add global usings:
<ItemGroup>
<Using Include="Xunit" />
<Using Include="Moq" />
<Using Include="FluentAssertions" />
</ItemGroup>
3. Test Directory Structure
Mirror source structure:
ProjectName.Tests/
├── Data/ # Database and EF Core tests
├── Models/ # Model validation tests
├── Services/
│ ├── Audio/ # Service-specific tests
│ ├── Clipping/
│ └── Transcript/
├── Helpers/ # Test utilities
└── Fixtures/ # Test data factories
4. Test Helper Patterns
In-Memory Database Factory:
public static class TestDbContextFactory
{
public static MyDbContext CreateInMemoryContext()
{
var options = new DbContextOptionsBuilder<MyDbContext>()
.UseInMemoryDatabase(databaseName: Guid.NewGuid().ToString())
.Options;
var context = new MyDbContext(options);
context.Database.EnsureCreated();
return context;
}
}
Test Data Fixtures:
public static class TestDataFixtures
{
public static MyEntity CreateTestEntity(int id = 1)
{
return new MyEntity
{
Id = id,
Name = "Test Entity",
CreatedAt = DateTime.UtcNow
};
}
}
5. Test Class Pattern
public class MyServiceTests : IDisposable
{
private readonly MyDbContext _context;
private readonly MyService _service;
public MyServiceTests()
{
_context = TestDbContextFactory.CreateInMemoryContext();
_service = new MyService(_context);
}
[Fact]
public async Task MethodName_Scenario_ExpectedBehavior()
{
var entity = TestDataFixtures.CreateTestEntity();
var result = await _service.ProcessAsync(entity);
result.Should().NotBeNull();
result.Status.Should().Be(ProcessStatus.Success);
}
public void Dispose()
{
_context?.Dispose();
}
}
Examples
Version compatibility check:
When adding EF Core InMemory, match the version from main project:
grep "Microsoft.EntityFrameworkCore" src/MainProject/MainProject.csproj
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="10.0.2" />
Running tests:
dotnet test
dotnet test --verbosity detailed
dotnet build
dotnet test --no-build
Anti-Patterns
❌ Don't use different target frameworks between main and test projects
❌ Don't share DbContext instances between tests (use unique database names)
❌ Don't hard-code entity IDs in test fixtures that will conflict
❌ Don't use latest package versions without checking compatibility
❌ Don't forget to dispose of DbContext in test cleanup
✅ Do use Guid.NewGuid() for unique in-memory database names
✅ Do match all framework versions between projects
✅ Do let database assign IDs for entities to avoid tracking conflicts
✅ Do implement IDisposable for proper resource cleanup
✅ Do use FluentAssertions for readable test assertions