关于 spring-jpa-testing
面向 Spring 开发者的 JPA 仓库测试技能,使用 `@DataJpaTest`。它强调以真实测试数据进行设置,并在读取断言前刷新和清除持久化上下文,确保查询实际访问数据库。
主要功能
- 01`@DataJpaTest` 设置模式
- 02使用 TestEntityManager 设置数据
- 03读取前刷新并清除上下文
- 04Testcontainers 配置指导
- 05事务测试问题排查
- 06Hibernate 迁移指导
适用场景
- 01测试仓库查询与分页
- 02验证数据库约束和批量更新
- 03排查延迟加载或事务测试问题
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ spring-ai-community/ spring-testing-skills --skill spring-jpa-testing安装后在 Claude Code 中输入/spring-jpa-testing确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/hibernate-6-migration.mdlazy-loading-tests.mdtestcontainers.mdtransactional-tests.md详细介绍
Spring JPA 测试
重要:@DataJpaTest 需要使用 TestEntityManager 设置测试数据,并在读取断言前调用 flush()+clear()。跳过这些步骤的测试会从 Hibernate L1 缓存读取数据,导致测试错误地通过——查询实际上从未在数据库中执行。详见下文“关键规则”。
相关信号:@DataJpaTest、JpaRepository、EntityManager、TestEntityManager、@ServiceConnection、PostgreSQLContainer、@AutoConfigureTestDatabase、@Modifying、clearAutomatically、Testcontainers、Hibernate 6、Hibernate 7
测试环境
- Spring Boot 3.2+ / Spring Boot 4.x
- Spring Framework 6.x / Spring Framework 7.x
- Hibernate 6.x / Hibernate 7.x
- JUnit 5、Testcontainers 1.19+
关键规则 — 在 @DataJpaTest 中始终遵守
1. 使用 TestEntityManager 设置测试数据——绝不要使用 Mockito 模拟对象。
@DataJpaTest 会提供真实的内存数据库。模拟 Repository 会违背测试的初衷。
使用 @Autowired TestEntityManager em 和 em.persist() / em.persistAndFlush() 插入测试数据。
不要使用待测 Repository 设置数据——这会造成循环逻辑,使 Repository 中的错误同时掩盖数据设置和断言失败。
2. 在读取断言前始终调用 flush() 和 clear()。
持久化测试数据后,在通过 Repository 查询前调用 em.flush(),然后调用 em.clear()。
如果不调用 flush,SQL 可能永远不会到达数据库。如果不调用 clear,Repository 会从
Hibernate L1 缓存返回实体——查询实际上从未在数据库中执行。
@DataJpaTest
class OrderRepositoryTest {
@Autowired TestEntityManager em;
@Autowired OrderRepository orders;
@Test
void findByStatus_returnsMatching() {
em.persist(new Order("pending"));
em.persist(new Order("shipped"));
em.flush(); // SQL hits the database
em.clear(); // L1 cache evicted — forces real DB read
List<Order> result = orders.findByStatus("pending");
assertThat(result).hasSize(1);
}
}
有关 @Modifying 批量更新、约束违反测试和 @Transactional 陷阱的完整模式,请参阅 references/transactional-tests.md。
不适用此技能的情况
- 测试 REST 控制器或 HTTP 端点 → 使用
spring-mvc-testing - 测试身份验证、授权、CSRF、JWT 或 OAuth2 → 使用
spring-security-testing - 测试响应式 Repository(R2DBC)或 WebClient → 使用
spring-webflux-testing - 编写不使用 Spring 上下文的纯单元测试 → 使用
spring-testing-fundamentals - 设置 AssertJ 断言或 Mockito 桩 → 使用
spring-testing-fundamentals
何时阅读参考资料
| 情况 | 阅读 |
|---|---|
使用 Testcontainers 和 @ServiceConnection 设置 @DataJpaTest | references/testcontainers.md |
在 @DataJpaTest 和 @SpringBootTest 之间进行选择 | references/testcontainers.md |
调试 @Transactional 回滚问题、flush/clear 问题或测试隔离问题 | references/transactional-tests.md |
编写测试模式:派生查询、@Query、分页、规格、投影、审计 | references/transactional-tests.md |
| 延迟加载在测试中有效但在生产环境中失败,或出现 N+1 问题 | references/lazy-loading-tests.md |
测试 SINGLE_TABLE 继承、只读 Repository、@QueryHint 陷阱 | references/lazy-loading-tests.md |
Hibernate 6.x 或 7.x 迁移失败、Jakarta 包、序列命名、ClassCastException | references/hibernate-6-migration.md |
| Boot 3.x → 4.x 测试包导入变更 | references/hibernate-6-migration.md |