You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Mockito测试JPA Service时,Repository的findById返回空Optional引发异常

解决Mockito测试editUser方法时的NoSuchElementException异常

问题根源

你的测试代码仅Mock了userRepository.save()方法,但未MockfindById()方法。当Service执行userRepository.findById(user.getUser_id()).get()时,findById返回空Optional,直接调用get()就会触发NoSuchElementException。

修复测试代码

需要在测试中补充对findById()的Mock,让它返回包含预设原有用户的Optional。修改后的测试代码如下:

@Test
void checkIfUserCanBeEdited(){
    // Mock findById,返回setup中创建的原有用户
    given(userRepository.findById(user.getUser_id())).willReturn(Optional.of(user));
    
    // 模拟保存后的返回结果(匹配任意User对象,返回加密密码后的用户)
    User expectedUser = new User(
        user.getUser_id(), 
        user.getUsername(), 
        passwordEncoder.encode("check"), 
        user.getGroup_id(), 
        user.getEmail(), 
        "user", 
        user.getActive()
    );
    given(userRepository.save(any(User.class))).willReturn(expectedUser);

    // 修改传入的用户属性
    user.setPassword("check");
    user.setRole("user");

    // 执行方法
    User updateUser = userService.editUser(user);

    // 断言验证
    assertThat(updateUser.getPassword()).isEqualTo(passwordEncoder.encode("check"));
    assertThat(updateUser.getRole()).isEqualTo("user");
}

注意:Service中对非空密码会执行加密操作,所以断言时要对比加密后的密码,而非明文"check",否则断言会失败。

优化Service代码(推荐)

原Service直接调用get()获取Optional值,未处理空值场景,生产环境也可能抛出异常。建议优化为:

@Override
public User editUser(User user) {
    // 找不到用户时抛出明确的业务异常
    User savedUser = userRepository.findById(user.getUser_id())
            .orElseThrow(() -> new IllegalArgumentException("用户不存在,ID:" + user.getUser_id()));
    
    User userToEdit = new User();
    userToEdit.setUser_id(user.getUser_id());
    userToEdit.setRole(user.getRole().isEmpty() ? savedUser.getRole() : user.getRole());
    userToEdit.setUsername(user.getUsername().isEmpty() ? savedUser.getUsername() : user.getUsername());
    userToEdit.setPassword(user.getPassword().isEmpty() ? savedUser.getPassword() : passwordEncoder.encode(user.getPassword()));
    userToEdit.setEmail(user.getEmail().isEmpty() ? savedUser.getEmail() : user.getEmail());
    userToEdit.setGroup_id((user.getGroup_id() == -1) ? savedUser.getGroup_id() : user.getGroup_id());
    userToEdit.setActive(user.getActive() != savedUser.getActive() ? savedUser.getActive() : user.getActive());

    return userRepository.save(userToEdit);
}

优化后无论测试还是生产环境,用户不存在时都会抛出更清晰的业务异常,而非泛化的NoSuchElementException。

内容的提问来源于stack exchange,提问作者m3k_1

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 02:01:27