mcpField
S
spring-jpa-testing

spring-jpa-testing

github.com/spring-ai-community测试与质量5243 次安装27 周前更新
代码仓库

关于 spring-jpa-testing

面向 Spring 开发者的 JPA 仓库测试技能,使用 `@DataJpaTest`。它强调以真实测试数据进行设置,并在读取断言前刷新和清除持久化上下文,确保查询实际访问数据库。

主要功能

  1. 01`@DataJpaTest` 设置模式
  2. 02使用 TestEntityManager 设置数据
  3. 03读取前刷新并清除上下文
  4. 04Testcontainers 配置指导
  5. 05事务测试问题排查
  6. 06Hibernate 迁移指导

适用场景

  1. 01测试仓库查询与分页
  2. 02验证数据库约束和批量更新
  3. 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.md
lazy-loading-tests.md
testcontainers.md
transactional-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 设置 @DataJpaTestreferences/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 包、序列命名、ClassCastExceptionreferences/hibernate-6-migration.md
Boot 3.x → 4.x 测试包导入变更references/hibernate-6-migration.md

评论

支持 Markdown