findById 看不到模拟中的对象

findById doesn't see the object from the mock

提问人:ezulex 提问时间:11/14/2023 最后编辑:ezulex 更新时间:11/17/2023 访问量:58

问:

我正在为 UserServiceImpl 服务编写测试。

    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;
    }

UserServiceImplTest

@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);
    }
}

在 userService.getUserById(id) 方法中运行测试时 - java.lang.RuntimeException:找不到 id 的用户:1 尽管存储库中存在具有相同 ID 的对象。 请告诉我我错过了什么?

java spring-boot junit mockito

评论

0赞 Reg 11/14/2023
嗨,您正在模拟 findAll 而不是 findById 方法。您在服务中使用了 findbyId。
0赞 J Asgarov 11/14/2023
您调用的方法调用存储库上的另一个方法 由于您从未模拟过它返回 null,因此您的异常userService.getUserById(id);userRepository.findById(id);userRepository.findById(id);
0赞 k314159 11/14/2023
顺便说一下,getUserById 方法可以缩短为一行:return userRepository.findById(id).orElseThrow(() -> new RuntimeException("User not found for id: " + id));

答:

1赞 bytez 11/14/2023 #1

这里的主要问题是你模拟的是 userRepository.findAll() 而不是 userRepository.findById(id)。

在实现中,您用于获取用户,但在测试中,您已经为 .这是两种不同的方法,Mockito 不知道在调用时如何响应,因为它没有被指示在这种情况下该怎么做。UserServiceImplfindById(id)findAll()findById(id)

要解决此问题,您需要模拟 的行为。这是你如何做到的:findById(id)

Mockito.when(userRepository.findById(eq(1L))).thenReturn(Optional.of(getUsers().get(0)));

请注意 eq 方法,它使您能够匹配传递给模拟的特定参数。


请注意,鉴于服务层的简单性,此测试可能不会测试有意义的行为,因为它模拟存储库并且不涵盖真实的数据库交互,因此可能缺少集成问题。

0赞 Achraf Lemghari 11/14/2023 #2

要修复它,您应该通过以下语法进行模拟:findById(id)

Mockito.when(userRepository.findById(any())).thenReturn(Optional.of(getUsers().get(0)));