关于 spring-boot-testing
spring-boot-testing 是面向 Spring Boot 4 应用开发者的测试指南,帮助选择测试范围和工具,并提供断言、Testcontainers、测试数据、性能及迁移参考。
主要功能
- 01测试切片选择指南
- 02MockMvcTester 与 RestTestClient 参考
- 03AssertJ 断言指南
- 04使用 Testcontainers 测试数据库
- 05覆盖率与上下文缓存建议
适用场景
- 01为控制器选择适当的测试
- 02针对数据库测试 JPA 查询
- 03测试 REST 客户端和 JSON 序列化
- 04规划 Spring Boot 4 测试迁移
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ marcelorodrigo/ agent-skills --skill spring-boot-testing安装后在 Claude Code 中输入/spring-boot-testing确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/assertj-basics.mdassertj-collections.mdcontext-caching.mddatajpatest.mdinstancio.mdmockitobean.mdmockmvc-classic.mdmockmvc-tester.mdrestclienttest.mdresttestclient.mdsb4-migration.mdtest-slices-overview.mdtestcontainers-jdbc.mdwebmvctest.md详细介绍
Spring Boot 测试
使用现代模式和最佳实践测试 Spring Boot 4 应用的专家指南。
核心原则
- 测试金字塔:单元测试(快速)> 切片测试(聚焦)> 集成测试(完整)
- 选择合适的工具:使用能让你获得足够信心的最小测试切片
- AssertJ 风格:优先使用流畅、易读的断言,而非冗长的匹配器
- 现代 API:优先使用 MockMvcTester 和 RestTestClient,而非旧版替代方案
该选择哪种测试切片?
| 场景 | 注解 | 参考 |
|---|---|---|
| 控制器 + HTTP 语义 | @WebMvcTest | references/webmvctest.md |
| Repository + JPA 查询 | @DataJpaTest | references/datajpatest.md |
| REST 客户端 + 外部 API | @RestClientTest | references/restclienttest.md |
| JSON(反)序列化 | @JsonTest | 参见 references/test-slices-overview.md |
| 完整应用 | @SpringBootTest | 参见 references/test-slices-overview.md |
测试切片参考
- references/test-slices-overview.md - 决策矩阵和比较
- references/webmvctest.md - 使用 MockMvc 测试 Web 层
- references/datajpatest.md - 使用 Testcontainers 测试数据层
- references/restclienttest.md - REST 客户端测试
测试工具参考
- references/mockmvc-tester.md - AssertJ 风格的 MockMvc(3.2+)
- references/mockmvc-classic.md - 传统 MockMvc(3.2 之前)
- references/resttestclient.md - Spring Boot 4+ REST 客户端
- references/mockitobean.md - 模拟依赖项
断言库
- references/assertj-basics.md - 标量、字符串、布尔值、日期
- references/assertj-collections.md - 列表、集合、映射、数组
Testcontainers
- references/testcontainers-jdbc.md - PostgreSQL、MySQL 等
测试数据生成
- references/instancio.md - 生成复杂测试对象(3 个以上属性)
性能与迁移
- references/context-caching.md - 加快测试套件运行速度
- references/sb4-migration.md - Spring Boot 4.0 的变更
快速决策树
Testing a controller endpoint?
Yes → @WebMvcTest with MockMvcTester
Testing repository queries?
Yes → @DataJpaTest with Testcontainers (real DB)
Testing business logic in service?
Yes → Plain JUnit + Mockito (no Spring context)
Testing external API client?
Yes → @RestClientTest with MockRestServiceServer
Testing JSON mapping?
Yes → @JsonTest
Need full integration test?
Yes → @SpringBootTest with minimal context config
Spring Boot 4 亮点
- RestTestClient:TestRestTemplate 的现代替代方案
- @MockitoBean:替代已弃用的 @MockBean
- MockMvcTester:用于 Web 测试的 AssertJ 风格断言
- 模块化 starter:针对特定技术的测试 starter
- 上下文暂停:自动暂停缓存的上下文(Spring Framework 7)
测试最佳实践
代码复杂度评估
当某个方法或类过于复杂,难以有效测试时:
- 分析复杂度 - 如果需要超过 5-7 个测试用例才能覆盖单个方法,它很可能过于复杂
- 建议重构 - 建议将代码拆分为更小、更聚焦的函数
- 由用户决定 - 如果用户同意重构,帮助确定提取代码的位置
- 必要时继续 - 如果用户决定继续使用复杂代码,即使测试有难度,也要编写测试
重构建议示例:
// Before: Complex method hard to test
public Order processOrder(OrderRequest request) {
// Validation, discount calculation, payment, inventory, notification...
// 50+ lines of mixed concerns
}
// After: Refactored into testable units
public Order processOrder(OrderRequest request) {
validateOrder(request);
var order = createOrder(request);
applyDiscount(order);
processPayment(order);
updateInventory(order);
sendNotification(order);
return order;
}
避免代码冗余
为常用对象和模拟设置创建辅助方法,以提高可读性和可维护性。
使用 @DisplayName 组织测试
使用描述性显示名称,明确测试意图:
@Test
@DisplayName("Should calculate discount for VIP customer")
void shouldCalculateDiscountForVip() { }
@Test
@DisplayName("Should reject order when customer has insufficient credit")
void shouldRejectOrderForInsufficientCredit() { }
测试覆盖顺序
始终按以下顺序组织测试:
- 主要场景 - 正常路径、最常见的用例
- 其他路径 - 其他有效场景、边界情况
- 异常/错误 - 无效输入、错误条件、失败模式
测试生产场景
编写测试时应考虑真实的生产场景。这样能让测试更贴近实际,也有助于理解代码在实际生产场景中的行为。
测试覆盖率目标
以 80% 的代码覆盖率为目标,在质量与投入之间取得切实可行的平衡。更高的覆盖率固然有益,但并非唯一目标。
使用 Jacoco maven 插件生成覆盖率报告并跟踪覆盖率。
覆盖率规则:
- 覆盖率至少达到 80%
- 注重有意义的断言,而不只是执行代码
优先测试的内容:
- 业务关键路径(支付处理、订单验证)
- 复杂算法(定价、折扣计算)
- 错误处理(异常、边界情况)
- 集成点(外部 API、数据库)
Dependencies (Spring Boot 4)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webmvc-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-testcontainers</artifactId>
<scope>test</scope>
</dependency>
评论
支持 Markdown