Click-tour 리펙토링 - (4)

지종권(JiJongKwon)·2023년 7월 28일

🚀 login 리펙토링

전에는 회원가입에 대한 리펙토링을 진행하였다.

이번에는 로그인에 관해 리펙토링을 하려고한다.

UserAPiController

수정 전 로그인 컨트롤러
	@PostMapping("/login")
    public ResponseEntity<?> login(@RequestBody UserLoginRequestDto userLoginRequestDto) {
        JwtTokenResponseDto jwtTokenResponseDto = new JwtTokenResponseDto(usersService.login(userLoginRequestDto));

        // Id가 존재하지 않을 때
        if (jwtTokenResponseDto.getJwtToken().equals("notFoundId")) {
            return new ResponseEntity<>(new ExceptionDto(ErrorMessage.NOT_FOUND_ID), HttpStatus.NOT_FOUND);
        }

        // 비밀번호가 틀릴 때
        if (jwtTokenResponseDto.getJwtToken().equals("mismatchPassword")) {
            return new ResponseEntity<>(new ExceptionDto(ErrorMessage.MISMATCH_PASSWORD), HttpStatus.BAD_REQUEST);
        }

        return new ResponseEntity<>(jwtTokenResponseDto, HttpStatus.OK);
    }

controller에 return이 3개나 있는 것이 거슬린다.

예외처리를 통해 리턴문을 제거하려 한다.

UserService

수정 전 로그인 메서드
	@Transactional
    public String login(UserLoginRequestDto userLoginRequestDto) {
        Optional<Users> users = usersRepository.findByLoginId(userLoginRequestDto.getLoginId());
        if (users.isEmpty()) {
            return "notFoundId";
        }
        if (!passwordEncoder.matches(userLoginRequestDto.getLoginPassword(), users.get().getLoginPassword())) {
            return "mismatchPassword";
        }

        return jwtTokenProvider.createToken(users.get().getLoginId(), users.get().getRole());
    }

우선 저기 체크하는 부분을 보면 String문을 리턴하는데 우리는 전에 만든 예외처리기를 통해 수정하려고 한다.

UserServiceUnitTest

    @Test
    void 아이디_화인(){
        // given
        String loginId = "test";
        Users mockUsers = new Users();

        when(usersRepository.findByLoginId(loginId)).thenReturn(Optional.of(mockUsers));

        // when
        Users result = usersService.checkId(loginId);

        // then
        assertNotNull(result);
        assertEquals(mockUsers,result);
    }

    @Test
    void 아이디_확인_예외처리() {
        // given
        String loginId = "nonExistentUser";

        // when
        when(usersRepository.findByLoginId(loginId)).thenReturn(Optional.empty());

        // then
        assertThrows(NotValidException.class, () -> usersService.checkId(loginId));
    }
    
    @Test
    void 비밀번호_확인(){
        // given
        String userPassword = "test";
        String requestPassword = "test";

        // when
        when(passwordEncoder.matches(requestPassword, userPassword)).thenReturn(true);

        // then
        assertDoesNotThrow(()-> usersService.checkPassword(userPassword,requestPassword));
    }

    @Test
    void 비밀번호_확인_예외처리(){
        // given
        String userPassword = "test";
        String requestPassword = "diff";

        // when

        // then
        assertThrows(NotValidException.class, () -> usersService.checkPassword(userPassword,requestPassword));
    }

먼저 테스트 코드를 작성했다
간단하게 해당 아이디가 존재하는지 만약 존재하지 않는다면 예외처리 발생을 확인하는 테스트 코드이다.
비밀번호는 같은 비밀번호가 맞는지 확인한 후 맞지않다면 예외처리 발생하는 테스트 코드이다.

	/**
     * check Id
     * @param loginId
     * @return Users
     */
    @Transactional
    public Users checkId(String loginId){
        return usersRepository.findByLoginId(loginId)
                .orElseThrow(() -> new NotValidException(List.of(ErrorMessage.NOT_FOUND_ID.getMessage())));
    }
    
	/**
     * check password
     * @param users
     * @param userLoginRequestDto
     */
    public void checkPassword(Users users, UserLoginRequestDto userLoginRequestDto){
        if (!passwordEncoder.matches(userLoginRequestDto.getLoginPassword(), users.getLoginPassword())) {
            throw new NotValidException(List.of(ErrorMessage.MISMATCH_PASSWORD.getMessage()));
        }
    }

아이디 확인과 비빌번호 확인 메서드를 만들었다.
위의 코드를 보면 전 회원가입에서 체크하는 것과 같이 조건에 일치하지 않는다면 throw Exception을 던져 예외처리를 진행한다.

수정 후 로그인 메서드
	/**
     * 로그인
     * @param userLoginRequestDto
     * @return Jwt token
     */
    public String login(UserLoginRequestDto userLoginRequestDto) {
        Users users = checkId(userLoginRequestDto.getLoginId());

        checkPassword(users.getLoginPassword(), userLoginRequestDto.getLoginPassword());

        return jwtTokenProvider.createToken(users.getLoginId(), users.getRole());
    }

그리고 메서드를 적용해 깔끔해진 모습이다.

이제 예외처리를 적용했으니 컨트롤러에 있는 return문은 모조리 지울 수 있다.

수정 후 로그인 컨트롤러
	/**
     * 로그인
     *
     * @param userLoginRequestDto
     * @return responseEntity
     */
    @PostMapping("/login")
    public ResponseEntity<?> login(@RequestBody UserLoginRequestDto userLoginRequestDto) {
        JwtTokenResponseDto jwtTokenResponseDto = new JwtTokenResponseDto(usersService.login(userLoginRequestDto));
        return new ResponseEntity<>(jwtTokenResponseDto, HttpStatus.OK);
    }

깔끔해졌다.

1개의 댓글

comment-user-thumbnail
2023년 7월 28일

많은 도움이 되었습니다, 감사합니다.

답글 달기