用途
本技能提供面向 C# 与 .NET 应用的测试模式与最佳实践,用于在编写或审查测试代码、搭建 .NET 项目测试基础设施、调试不稳定或缓慢测试时参考。
推荐测试工具栈
- xUnit:测试框架(.NET 下首选)
- FluentAssertions:更易读的断言语法
- NSubstitute 或 Moq:模拟依赖
- Testcontainers:在集成测试中使用真实基础设施
- WebApplicationFactory:ASP.NET Core 集成测试
- Bogus:生成真实感的测试数据
主要能力与示例
单元测试结构(Arrange-Act-Assert)
示例中定义了 OrderServiceTests,通过 Substitute.For<IOrderRepository>() 与 Substitute.For<ILogger<OrderService>>() 构造被测对象 OrderService,并用 [Fact] 测试 PlaceOrderAsync 在有效请求下返回成功、在无商品项时返回失败。
Theory 参数化测试
支持 [InlineData] 与 [MemberData] 两种方式。示例分别用内联数据验证邮箱地址,以及用 TheoryData<CreateOrderRequest, string> 提供多组非法订单用例并断言错误信息。
使用 NSubstitute 进行模拟
示例展示两种用法:配置 FindByIdAsync 返回 null 以验证未找到场景;以及通过 _repository.Received(1).AddAsync(...) 验证仓库方法被按预期调用与参数匹配。
ASP.NET Core 集成测试
通过实现 IClassFixture<WebApplicationFactory<Program>>,在 WithWebHostBuilder 中调用 ConfigureServices,用 RemoveAll<DbContextOptions<AppDbContext>>() 移除真实数据库配置并替换为 UseInMemoryDatabase("TestDb"),再 CreateClient() 获得 HttpClient,随后用 [Fact] 断言 404 与 201 等 HTTP 响应。
使用 Testcontainers 的集成测试
示例实现 IAsyncLifetime,用 PostgreSqlBuilder().WithImage("postgres:16-alpine").Build() 创建容器,在 InitializeAsync 中 StartAsync 后通过 GetConnectionString() 配置 UseNpgsql 并执行 MigrateAsync,在 DisposeAsync 中释放上下文与容器;测试断言 AddAsync 后能通过 FindByIdAsync 持久化读出。
测试组织
给出目录结构:MyApp.UnitTests(按 Services、Validators 分类)、MyApp.IntegrationTests(按 Api、Repositories 分类)、MyApp.TestHelpers(含 Builders、Fixtures)。
测试数据 Builder
示例 OrderBuilder 提供 WithCustomer、WithItem 链式方法与 Build(),用于构造订单测试数据。
常见反模式与修正
包括:测试实现细节应改为测试行为与结果;共享可变测试状态应改为每个测试新实例(xUnit 通过构造函数实现);异步测试中的 Thread.Sleep 应改用带超时的 Task.Delay 或轮询辅助;断言 ToString() 输出应改为断言类型化属性;一个巨型断言应改为每个测试一个逻辑断言;用实现描述命名测试应改为按行为命名(Method_ExpectedResult_WhenCondition);忽略 CancellationToken 应始终传递并验证取消。
使用方式(运行测试)
# Run all tests
dotnet test
# Run with coverage
dotnet test --collect:"XPlat Code Coverage"
# Run specific project
dotnet test tests/MyApp.UnitTests/
# Filter by test name
dotnet test --filter "FullyQualifiedName~OrderService"
# Watch mode during development
dotnet watch test --project tests/MyApp.UnitTests/
适用场景
编写 C# 代码的新测试、审查测试质量与覆盖率、为 .NET 项目搭建测试基础设施、调试不稳定或缓慢的测试。
限制
暂未提供关于版本要求、平台限制、收费与价格等信息。