카테고리 없음
[Spring]_심화 개인 과제 트러블슈팅
cork-7
2025. 2. 27. 14:02
레벨 1
1. 코드 개선 퀴즈 - Early Return
@Transactional
public SignupResponse signup(SignupRequest signupRequest) {
String encodedPassword = passwordEncoder.encode(signupRequest.getPassword());
UserRole userRole = UserRole.of(signupRequest.getUserRole());
if (userRepository.existsByEmail(signupRequest.getEmail())) {
throw new InvalidRequestException("이미 존재하는 이메일입니다.");
}
User newUser = new User(
signupRequest.getEmail(),
encodedPassword,
userRole
);
User savedUser = userRepository.save(newUser);
String bearerToken = jwtUtil.createToken(savedUser.getId(), savedUser.getEmail(), userRole);
return new SignupResponse(bearerToken);
}
기본 코드에서 이메일 확인 로직이 passwordEncoder 뒤쪽에 위치해 이미 존재하는 이메일을 사용시 위 로직이 불필요하게 동작
if (userRepository.existsByEmail(signupRequest.getEmail())) {
throw new InvalidRequestException("이미 존재하는 이메일입니다.");
}
String encodedPassword = passwordEncoder.encode(signupRequest.getPassword());
UserRole userRole = UserRole.of(signupRequest.getUserRole());
User newUser = new User(
signupRequest.getEmail(),
encodedPassword,
userRole
);
이메일 확인로직이 위로 가게 작성
2. 리팩토링 퀴즈 - 불필요한 if-else 피하기
WeatherDto[] weatherArray = responseEntity.getBody();
if (!HttpStatus.OK.equals(responseEntity.getStatusCode())) {
throw new ServerException("날씨 데이터를 가져오는데 실패했습니다. 상태 코드: " + responseEntity.getStatusCode());
} else {
if (weatherArray == null || weatherArray.length == 0) {
throw new ServerException("날씨 데이터가 없습니다.");
}
}
if else-if문은 첫 if문과 반대되고 다른 조건을 걸어야할 때 사용한다 다만 현재 로직에서 굳이 else로 묶지 않고 if문으로 작성해도 이상이 없고 가독성에 좋다
WeatherDto[] weatherArray = responseEntity.getBody();
if (!HttpStatus.OK.equals(responseEntity.getStatusCode())) {
throw new ServerException("날씨 데이터를 가져오는데 실패했습니다. 상태 코드: " + responseEntity.getStatusCode());
}
if (weatherArray == null || weatherArray.length == 0) {
throw new ServerException("날씨 데이터가 없습니다.");
}
3. 코드 개선 퀴즈 - Validation
비밀번호 변경시 검증로직을 DTO로 옮기자
@NotBlank
private String oldPassword;
@NotBlank
@Pattern(regexp = "(?=.*\\d.*)(?=.*[A-Z].*).{8,}", message = "새 비밀번호는 8자 이상이어야 하고, 숫자와 대문자를 포함해야 합니다.")
private String newPassword;
레벨 2
N+1 문제
@Query("SELECT t FROM Todo t LEFT JOIN FETCH t.user u ORDER BY t.modifiedAt DESC")
Page<Todo> findAllByOrderByModifiedAtDesc(Pageable pageable);
todoController와 todoService에서 발생하는 N+1문제를 해결하기 위해 작성된 todoRepository로직이다.
이와 같은 동작을 하는 EntityGraph로 작성해보자
@EntityGraph(attributePaths = {"user"})
Page<Todo> findAllByOrderByModifiedAtDesc(Pageable pageable);
레벨 3
테스트 코드 연습 - 1
encode를 하는 encodedPassword가 앞에 있어 에러발생
@Test
void matches_메서드가_정상적으로_동작한다() {
// given
String rawPassword = "testPassword";
String encodedPassword = passwordEncoder.encode(rawPassword);
// when
boolean matches = passwordEncoder.matches(rawPassword, encodedPassword);
// then
assertTrue(matches);
}
테스트 코드 연습 - 2-1
expected의 메세지와 메소드명이 틀리다
@Test
public void manager_목록_조회_시_Todo가_없다면_IRE_에러를_던진다() {
// given
long todoId = 1L;
given(todoRepository.findById(todoId)).willReturn(Optional.empty());
// when & then
InvalidRequestException exception = assertThrows(InvalidRequestException.class, () -> managerService.getManagers(todoId));
assertEquals("Todo not found", exception.getMessage());
}
테스트 코드 연습 - 2-2
exception이 잘못 적혀있다
@Test
public void comment_등록_중_할일을_찾지_못해_에러가_발생한다() {
// given
long todoId = 1;
CommentSaveRequest request = new CommentSaveRequest("contents");
AuthUser authUser = new AuthUser(1L, "email", UserRole.USER);
given(todoRepository.findById(anyLong())).willReturn(Optional.empty());
// when
InvalidRequestException exception = assertThrows(InvalidRequestException.class, () -> {
commentService.saveComment(authUser, todoId, request);
});
// then
assertEquals("Todo not found", exception.getMessage());
}
테스트 코드 연습 - 2-3
유저가 null인 상황이 서비스 로직에 들어가 있지 않아 메세지가 안뜨고 에러가 발생
Transactional
public ManagerSaveResponse saveManager(AuthUser authUser, long todoId, ManagerSaveRequest managerSaveRequest) {
// 일정을 만든 유저
User user = User.fromAuthUser(authUser);
Todo todo = todoRepository.findById(todoId)
.orElseThrow(() -> new InvalidRequestException("Todo not found"));
if (todo.getUser() == null || !ObjectUtils.nullSafeEquals(user.getId(), todo.getUser().getId())) {
throw new InvalidRequestException("담당자를 등록하려고 하는 유저가 일정을 만든 유저가 유효하지 않습니다.");
}
if문에 null 추가