Spring Boot测试中UserRepository无法正常工作的问题排查
问题根源与解决方案
核心问题:存根(mock)覆盖了真实的保存逻辑
你在@BeforeEach中对userRepo.save()做了硬编码存根:
Mockito.when(userRepo.save(Mockito.any(UserEntity.class))).thenReturn(new UserEntity());
这段代码强制save()方法返回一个空的UserEntity实例,完全跳过了Spring Data JPA的真实保存逻辑——既不会把数据写入数据库,返回的对象自然全是null。
同时你用了@Spy修饰UserRepo,存根会覆盖Spy的默认行为(原本Spy会优先调用真实方法),导致真实的数据库操作完全没执行。
分场景解决方案
场景1:只想做单元测试(不操作真实数据库)
如果只是测试UserService的逻辑,不需要真的写库:
- 替换测试类注解:去掉
@SpringBootTest,用@ExtendWith(MockitoExtension.class)简化Mock环境 - 修改存根逻辑,返回带字段的实体,匹配传入的参数:
@BeforeEach public void setupMock() { // 让save返回传入的实体(模拟保存成功并返回带数据的对象) Mockito.when(userRepo.save(Mockito.any(UserEntity.class))) .thenAnswer(invocation -> { UserEntity input = invocation.getArgument(0); // 手动设置ID模拟数据库自增 input.setId(1L); return input; }); // 存根findByPhoneNumber,返回对应实体 Mockito.when(userRepo.findByPhoneNumber(Mockito.anyString())) .thenAnswer(invocation -> { String phone = invocation.getArgument(0); Optional<UserEntity> user = getUserAddModels().stream() .filter(m -> m.getPhoneNumber().equals(phone)) .map(m -> { UserEntity entity = new UserEntity(); entity.setId(1L); entity.setFirstName(m.getFirstName()); entity.setLastName(m.getLastName()); entity.setPatronymic(m.getPatronymic()); entity.setPhoneNumber(m.getPhoneNumber()); entity.setEmail(m.getEmail()); return entity; }) .findFirst(); return user; }); } - 删除
@AfterEach里的删库逻辑,因为未操作真实数据库。
场景2:做集成测试(操作真实数据库)
如果要验证真实的数据库保存逻辑:
- 去掉
@InjectMocks、@Spy注解,改用@Autowired注入真实Bean:@SpringBootTest @TestMethodOrder(MethodOrderer.OrderAnnotation.class) public class UserServiceTest { @Autowired private UserService userService; @Autowired private UserRepo userRepo; @Autowired private ValidationService validationService; @Autowired private PasswordEncoder passwordEncoder; // 保留@AfterEach删库逻辑,避免测试数据污染 @AfterEach public void deleteDb() { userRepo.deleteAll(); } // 删除@BeforeEach里的存根代码,让Spring Data JPA执行真实save逻辑 @BeforeEach public void setupMock() {} // 测试方法保持不变 @Test @Order(1) public void testUserAdding() { // ... 原有代码 } } - 确保测试用数据库配置正确(比如用H2内存库,避免影响生产数据)。
额外排查点
- 检查
UserEntity注解:确认@Entity、@Id、@GeneratedValue等注解配置正确,保证JPA能识别实体和主键生成策略。 - 检查
UserRepo继承关系:确认继承了JpaRepository或CrudRepository,确保Spring Data JPA能生成正确的实现类。
内容的提问来源于stack exchange,提问作者Cross
相关产品推荐
相关产品推荐

