Mockito模拟JPA Repository返回列表仅首元素非空问题排查
问题原因与解决方法
核心错误:对象赋值时的变量名误用
你在测试类中初始化entity1和entity2的代码完全写错了——创建entity1之后,你仍然在操作entity对象,而非entity1;同理entity2也是如此。这导致entity1和entity2自始至终都是只被实例化但未设置任何属性的空对象(PasteboxEntity用了@Data,未赋值的引用类型属性默认是null,基本类型isPublic默认是false),所以列表里的后两个元素自然呈现“空”状态。
错误代码片段
PasteboxEntity entity1 = new PasteboxEntity(); // 错误:操作了entity,而非entity1 entity.setId(1L); entity.setHash("hash1"); entity.setData("Here's my text #2."); entity.setLifeTime(expTime1); entity.setPublic(true); PasteboxEntity entity2 = new PasteboxEntity(); // 错误:操作了entity,而非entity2 entity.setId(2L); entity.setHash("hash2"); entity.setData("Here's my text #3."); entity.setLifeTime(expTime2); entity.setPublic(true);
修正后的测试类代码
@SpringBootTest public class PasteboxServiceTests { @Autowired PasteboxService pasteboxService; @MockBean PasteboxJPARepository pasteboxJPARepository; @Test void testFindAll(){ LocalDateTime now = LocalDateTime.now(); LocalDateTime expTime = now.plusSeconds(45); LocalDateTime expTime1 = now.plusSeconds(40); LocalDateTime expTime2 = now.plusSeconds(35); PasteboxEntity entity = new PasteboxEntity(); entity.setId(0L); entity.setHash("hash"); entity.setData("Here's my text #1."); entity.setLifeTime(expTime); entity.setPublic(true); PasteboxEntity entity1 = new PasteboxEntity(); // 改为操作entity1 entity1.setId(1L); entity1.setHash("hash1"); entity1.setData("Here's my text #2."); entity1.setLifeTime(expTime1); entity1.setPublic(true); PasteboxEntity entity2 = new PasteboxEntity(); // 改为操作entity2 entity2.setId(2L); entity2.setHash("hash2"); entity2.setData("Here's my text #3."); entity2.setLifeTime(expTime2); entity2.setPublic(true); List<PasteboxEntity> entities = new ArrayList<>(); entities.add(entity); entities.add(entity1); entities.add(entity2); when(pasteboxJPARepository.findAll()).thenReturn(entities); assertEquals(3, pasteboxService.testMethodEntity().size()); } }
额外优化建议
- 移除Repository中冗余的findAll方法:
JpaRepository已经继承了CrudRepository,自带findAll()方法,不需要在PasteboxJPARepository中重复声明,直接删除即可:
@Repository public interface PasteboxJPARepository extends JpaRepository<PasteboxEntity, Long> { PasteboxEntity findByHash(String hash); // 删除List<PasteboxEntity> findAll(); }
- 使用Builder模式简化对象初始化:结合
@Builder注解(需引入Lombok依赖)可以避免变量名写错的问题,同时让代码更简洁:
@Data @Entity @Table(name = "paste_box_entities") @Builder public class PasteboxEntity { // 原有属性保持不变 }
测试中创建对象的方式改为:
PasteboxEntity entity = PasteboxEntity.builder() .id(0L) .hash("hash") .data("Here's my text #1.") .lifeTime(expTime) .isPublic(true) .build();
内容的提问来源于stack exchange,提问作者Lacky YT
相关产品推荐
相关产品推荐

