Testing Architecture
The solution includes four test projects:Test Types
Unit Tests
Fast, isolated tests for business logic without external dependencies
Functional Tests
End-to-end API tests with real database and HTTP requests
Integration Tests
Test infrastructure components like database access and external services
Running Tests
Run All Tests
Run Specific Test Project
Run with Code Coverage
Run Specific Test
Verbose Output
Unit Tests
Unit tests verify isolated components without external dependencies.Test Structure
Unit tests are organized to mirror the Application structure:Dependencies
Fromtests/Application.UnitTests/Application.UnitTests.csproj:
Writing Unit Tests
Example fromtests/Application.UnitTests/Common/Behaviours/RequestLoggerTests.cs:
Unit Test Patterns
Arrange-Act-Assert (AAA)
Arrange-Act-Assert (AAA)
Structure tests in three clear sections:
Mocking with Moq
Mocking with Moq
Mock dependencies to isolate the unit under test:
Assertions with FluentAssertions
Assertions with FluentAssertions
Write readable assertions:
Functional Tests
Functional tests verify end-to-end API behavior with a real database.Test Infrastructure
Functional tests use a custom test fixture fromtests/Application.FunctionalTests/Testing.cs:
Writing Functional Tests
Base test class fromtests/Application.FunctionalTests/BaseTestFixture.cs:
Database Reset with Respawn
Functional tests use Respawn to reset the database between tests:Test Database Options
The test suite supports multiple database providers:- SQL Server LocalDB - For Windows development
- Testcontainers - For Linux/Docker environments
tests/Application.FunctionalTests/Application.FunctionalTests.csproj:
Integration Tests
Integration tests verify Infrastructure components interact correctly with external dependencies.Test Structure
Writing Integration Tests
Test Best Practices
Test Naming
Test Naming
Use descriptive names that explain what is being tested:
One Assert Per Test
One Assert Per Test
Focus each test on a single behavior:
Test Data Builders
Test Data Builders
Use builders for complex test data:
Async Tests
Async Tests
Always await async operations:
Test Coverage
Measuring Coverage
Generate coverage reports:Coverage Goals
Aim for these coverage targets:- Application Layer: 80%+ (business logic)
- Domain Layer: 90%+ (core entities and rules)
- Infrastructure Layer: 60%+ (integration points)
- Web Layer: 50%+ (controllers and middleware)
Viewing Coverage Reports
Use ReportGenerator to create HTML reports:Continuous Integration
Run tests in CI/CD pipelines:GitHub Actions
Troubleshooting
Tests Timing Out
Increase timeout for long-running tests:Database Locks
Ensure tests properly dispose of database connections:Flaky Tests
Identify and fix non-deterministic behavior:Next Steps
Creating Use Cases
Write testable CQRS handlers
Configuration
Configure test environments