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

Mockito测试:UserServiceImpl的findById无法识别Mock对象求助

问题:getUserById测试抛出用户未找到异常,明明Mock了对应ID的对象

我在为UserServiceImpl编写测试时遇到问题:调用userService.getUserById(id)抛出java.lang.RuntimeException: User not found for id: 1异常,但Mock的仓库里明明有相同ID的对象。

业务代码

public User getUserById(long id) {
    Optional<User> optional = userRepository.findById(id);
    User user = null;
    if (optional.isPresent()) {
        user = optional.get();
    } else {
        throw new RuntimeException("User not found for id: " + id);
    }
    return user;
}

测试代码

@ExtendWith(MockitoExtension.class)
public class UserServiceImplTest {

    @Mock
    private UserRepository userRepository;
    @InjectMocks
    private UserServiceImpl userService;

    @Test
    public void shouldReturnUserById() {
        List<User> users = getUsers();
        Long id = 1L;

        Mockito.when(userRepository.findAll()).thenReturn(users);

        System.out.println(users.get(0).getId());

        User result = userService.getUserById(id);

        Assertions.assertNotNull(result);
        Assertions.assertEquals(users.get(0), result);
    }

    private List<User> getUsers() {
        User firstUser = new User();
        User secondUser = new User();

        firstUser.setId(1L);
        firstUser.setName("Rob");
        firstUser.setLastName("King");
        firstUser.setDepartment("Supply");
        firstUser.setPosition("Team lead");

        secondUser.setId(2L);
        secondUser.setName("Mike");
        secondUser.setLastName("Wilson");
        secondUser.setDepartment("Sale");
        secondUser.setPosition("Specialist");

        return List.of(firstUser, secondUser);
    }
}

问题原因与修复

原因

测试代码中Mock的是userRepository.findAll()的返回值,但getUserById方法实际调用的是userRepository.findById(id),这个方法未被Mock,Mockito会返回默认的空Optional,触发异常。

修复方案

将Mock的目标方法改为findById,针对传入的ID返回对应的用户对象:

修正后的测试方法代码:

@Test
public void shouldReturnUserById() {
    List<User> users = getUsers();
    Long id = 1L;
    // 获取对应ID的预期用户
    User expectedUser = users.stream()
                             .filter(u -> u.getId().equals(id))
                             .findFirst()
                             .orElseThrow();
    // Mock findById方法,传入指定ID时返回该用户的Optional
    Mockito.when(userRepository.findById(id)).thenReturn(Optional.of(expectedUser));

    User result = userService.getUserById(id);

    Assertions.assertNotNull(result);
    Assertions.assertEquals(expectedUser, result);
    // 可选:验证findById方法是否被调用过一次
    Mockito.verify(userRepository, Mockito.times(1)).findById(id);
}

额外建议

给User类重写equals()和hashCode()方法,否则Assertions.assertEquals会默认比较对象引用,可能导致预期外的断言失败。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 11:01:20