Spring Boot Gradle项目JUnit5 Repository测试类执行报错求助
问题分析与解决方案
问题根源
- ID生成策略冲突:Domain实体的
id采用GenerationType.IDENTITY自增策略,但测试代码中手动给实体硬编码id=1。H2内存库的自增序列不会随事务回滚重置,当多个测试方法连续运行时,后续测试中domainRepository.save(domain)生成的实际ID会是2、3...而非手动指定的1。 - 关联实体引用错误:
createTopic()方法中新建了一个独立的Domain对象并设置id=1,而非使用@BeforeEach中创建的Domain实例。后续测试中,Topic关联的id=1Domain在当前事务中不存在,触发关联查找失败。
修复步骤
1. 移除手动设置ID的代码
因为使用自增策略,无需手动指定ID,让JPA自动生成:
private Domain createDomain() { Domain domain = new Domain(); domain.setName("Java"); domain.setUid("1234z637-c6c1-4dc3-9755-9f6ad974d70b"); return domain; } private Topic createTopic(Domain domain) { // 接收已创建的Domain实例 Topic topic = new Topic(); topic.setName("Java"); topic.setUid("35f66eaa-2fc7-4170-8470-feb83ddbf6b0"); topic.setDomain(domain); // 使用传入的Domain实例,保证关联正确性 return topic; }
2. 调整测试初始化与保存逻辑
确保Topic关联的是保存后的Domain实例(包含自动生成的ID):
@BeforeEach void addTestRecord() { domain = createDomain(); topic = createTopic(domain); // 传入domain实例 } @Test void findAllTopicByDomainId() { // 保存后获取带生成ID的Domain实体 Domain savedDomain = domainRepository.save(domain); // 更新Topic的Domain引用为保存后的实例 topic.setDomain(savedDomain); topicRepository.save(topic); final var result = topicRepository.findAllTopicByDomainId("1234z637-c6c1-4dc3-9755-9f6ad974d70b"); assertEquals(1, result.size()); assertEquals("Java", result.get(0).getName()); } @Test void deleteByUid() { Domain savedDomain = domainRepository.save(domain); topic.setDomain(savedDomain); topicRepository.save(topic); assertTrue(topicRepository.findById(topic.getId()).isPresent()); topicRepository.deleteByUid(topic.getUid()); assertFalse(topicRepository.findById(topic.getId()).isPresent()); } @Test void getTopicByUid() { Domain savedDomain = domainRepository.save(domain); topic.setDomain(savedDomain); topicRepository.save(topic); final var result = topicRepository.getTopicByUid(topic.getUid()); assertEquals("Java", result.getName()); }
3. 可选:禁用事务回滚(不推荐)
若不想修改代码,可给测试类添加@Transactional(propagation = Propagation.NOT_SUPPORTED),但此方式会导致测试数据在方法间共享,引发测试耦合,不建议使用。
单独运行测试正常的原因
单独运行时,单个测试方法的事务中,domainRepository.save(domain)生成的ID为1,Topic关联的id=1Domain存在,因此测试通过。连续运行时,H2自增序列不会因事务回滚重置,后续测试生成的Domain ID递增,而Topic仍关联id=1,导致实体查找失败。
内容的提问来源于stack exchange,提问作者Anup Panchal
相关产品推荐
相关产品推荐

