9.3 API 集成测试
集成测试验证真实应用管线中的路由、依赖注入、配置、数据库和响应格式。它比单元测试慢,但能覆盖单元测试看不到的协作问题。
学习目标
- 能使用
WebApplicationFactory启动测试服务器。 - 能用
HttpClient调用 API 并断言响应。 - 能为测试使用隔离数据库或替代依赖。
- 能覆盖成功和失败路径。
应用场景
- 验证
POST /todos的 201 和 400 响应。 - 验证认证中间件、CORS、错误处理和 JSON 格式。
- 发布前确保核心 API 契约没有被破坏。
示例测试
public sealed class TodoApiTests : IClassFixture<WebApplicationFactory<Program>>
{
private readonly HttpClient client;
public TodoApiTests(WebApplicationFactory<Program> factory)
{
client = factory.CreateClient();
}
[Fact]
public async Task CreateTodo_ReturnsCreated_WhenTitleIsValid()
{
var response = await client.PostAsJsonAsync("/todos", new
{
Title = "学习集成测试",
Description = "覆盖创建任务接口",
});
response.StatusCode.Should().Be(HttpStatusCode.Created);
var todo = await response.Content.ReadFromJsonAsync<TodoDto>();
todo.Should().NotBeNull();
todo!.Title.Should().Be("学习集成测试");
}
}
测试数据策略
| 策略 | 适合场景 | 注意点 |
|---|---|---|
| 内存替代服务 | 快速验证 API 契约 | 不能覆盖真实数据库行为 |
| SQLite 内存库 | 验证 EF Core 基础行为 | 与 SQL Server 方言有差异 |
| Testcontainers | 接近生产数据库 | 需要 Docker 环境,速度较慢 |
重点难点
- 集成测试要隔离数据,避免测试之间互相污染。
- 不要只测成功路径,400、401、403、404 同样重要。
- API 响应契约要断言字段、状态码和错误格式。
- 测试失败时要能快速定位是路由、服务、数据库还是配置问题。
常见误区
| 误区 | 推荐做法 |
|---|---|
| 集成测试依赖开发库 | 每次测试使用独立数据库或事务清理 |
| 只断言状态码 | 同时断言响应体关键字段 |
| 所有逻辑都靠集成测试覆盖 | 单元测试覆盖业务规则,集成测试覆盖协作边界 |
练习
- 为标题为空的创建请求写 400 测试。
- 为不存在任务的完成请求写 404 测试。
- 给测试工厂替换连接字符串,使用独立测试数据库。