전에는 회원가입에 대한 리펙토링을 진행하였다.
이번에는 로그인에 관해 리펙토링을 하려고한다.
수정 전 로그인 컨트롤러
@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개나 있는 것이 거슬린다.
예외처리를 통해 리턴문을 제거하려 한다.
수정 전 로그인 메서드
@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문을 리턴하는데 우리는 전에 만든 예외처리기를 통해 수정하려고 한다.
@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);
}
깔끔해졌다.
많은 도움이 되었습니다, 감사합니다.