Search code examples
springspring-bootexceptiontestingmockito

Spring Boot Testing same exception scenarios in different methods


I was wondering if this is good approach. I'm writing unit test for my UserService class, there I've method that return UserDTO, inside of it I'm using fidUserByUsername method

    @Override
    public UserDTO getUserByUsername(String username) {
        log.info("Getting user with username {}", username);
        User user = findUserByUsername(username);
        return UserMapper.buildUserDTO(user);
    }

    public User findUserByUsername(String username) {
        log.info("Finding user with username {}", username);
        return userRepository.findByUsername(username)
                .orElseThrow(() -> {
                    String errorMessage = String.format(USER_DOESNT_EXIST_EXCEPTION, username);
                    log.error(EXCEPTION_OCCURRED, new UserDoesntExistException(errorMessage));
                    return new UserDoesntExistException(errorMessage);
                });
    }

But also in changeRole method I'm using same method to find user

    @Override
    public UserDTO changeRole(String username, String roleName) {
        
        User user = findUserByUsername(username);
        
        log.info("Changing role of user with username {} to role {}", username, roleName);
        String currentUsersRole = user.getRole().getName();
        if (currentUsersRole.equals(roleName)) {
            log.error(EXCEPTION_OCCURRED, new RoleException(USER_HAS_THAT_ROLE_EXCEPTION));
            throw new RoleException(USER_HAS_THAT_ROLE_EXCEPTION);
        }...

My question is, should I write a separated test for those scenario, or I should write just singe test case and no bother to write same scenario but for different method.

        @Test
        void shouldThrowUserDoesntExistException_WhenUserDoesntExist() {
            assertThrows(UserDoesntExistException.class, () -> userService.getUserByUsername(USERNAME_USER));
        }
        @Test
        void shouldThrowRoleExcddweption_W() {
            assertThrows(UserDoesntExistException.class, () -> userService.changeRole(USERNAME_USER, ROLE_NAME_ADMIN));
        }

Solution

  • "Dogmatically" speaking: Yes.

    Practically speaking: It's up to you and your team. If I were on your team, I'd strongly argue that the tests are valuable, since they help to define and enforce the method's complete contract, including its behavior (normal, edge-case, and otherwise).

    This could be the case when you need to remove one of these methods and you will still have the tested method with findUserByUsername() scenario