Junit에서 Service 예외처리 비교할때 에러 발생(예외처리 없음)

배지원·2023년 1월 9일
0

에러

목록 보기
5/7

게시물을 만드는 프로젝트를 진행하다보니 유저나 포스트의 내용을 비교하는 일이 많아졌다.
예를 들어

1. 정의

(1). 현재 로그인한 유저에 대한 데이터 찾기

    public User userDBCheck(String userName){
        return userRepository.findByUserName(userName)
                .orElseThrow(() -> new AppException(ErrorCode.USERNAME_NOT_FOUND));
    }
  • 일반적으로 현재 토큰에 담긴 유저 이름을 통해 해당 유저의 데이터를 찾아와 비교한다.
  • 만약 해당 유저 이름에 대한 데이터가 DB에 없을경우 .orElseThrow을 통해 예외처리를 한다.
  • 위와 같은 코드는 인가를 허용해야지만 접근이 가능한 API에서는 거의 다 호출하여 사용한다

(2). 현재 게시물 번호에 대한 데이터 찾기

    public Post postDBCheck(Long id){
        return postRepository.findById(id)
                .orElseThrow(() -> new AppException(ErrorCode.DATABASE_ERROR));
    }
  • 1번의 방식과 비슷하게 현재 게시물의 번호를 입력받아 해당 게시물의 데이터를 찾아온다.
  • 해당 데이터가 DB에 없을경우 .orElseThrow를 통해 에외처리 한다.
  • 위와 같은 코드는 해당 게시물을 수정, 삭제하던지 좋아요, 댓글등을 남길때 호출한다.


위와 같이 여러곳에서 중복적으로 사용하는 코드는 코드 중복을 방지하기 위해 Exception Class를 통해 중복되는 코드를 분리시켜 호출하여 사용하는 방식으로 구현을 했다.

하지만 PostMan을 통해 동작을 했을때는 정상적으로 동작을 하지만 Junit에서 Test를 할때는 오류가 발생했다.

2. 실습

Service

    // 1. 포스트 새로 작성
    public PostCreateResponse postCreate(PostCreateRequest postCreateRequest, String userName){

        User user = userException.userDBCheck(userName);

        Post post = postRepository.save(postCreateRequest.toEntity(user));  // Post DB에 유저가 입력한 제목,내용 저장

        if(post == null){
            return PostCreateResponse.error();      // DB에서 오류가 발생하여 post값을 받아오지 못하면 "저장실패" 오류 출력
        }else {
            return PostCreateResponse.success(post.getId());    // 정상동작시 "등록 완료" 출력
        }
    }

Exception

    public Post postDBCheck(Long id){
        return postRepository.findById(id)
                .orElseThrow(() -> new AppException(ErrorCode.DATABASE_ERROR));
    }

Junit

    @Test
    @DisplayName("1. 포스트 등록 실패 - 로그인 안함")
    void postCreate_fail(){

        when(userException.optionalUserDBCheck(userName))
                    .thenReturn(Optional.empty());           // userName을 통해 DB에서 해당 데이터를 찾았지만 없을 경우 상황 설정
        when(postRepository.save(any()))
                    .thenReturn(PostEntityFixture.postEntity("han","1234"));    // 포스트 데이터 저장

        PostCreateRequest request = new PostCreateRequest(title,body);

        AppException exception = Assertions.assertThrows(AppException.class,() -> postService.postCreate(request,userName));        // userName을 통해 찾은 데이터가 없으므로 예외처리가 발생함
        assertEquals(ErrorCode.USERNAME_NOT_FOUND, exception.getErrorCode());
    }

오류

  • 해당 오류는 postService.postCreate 메서드에 던질 에러가 없다는 뜻이다.
  • 즉, 현재 Exception클래스 안에서 예외처리를 하고 있는데 동작은 정상이지만 Junit에서는 해당 예외를 찾을 수 없다는 뜻이다.
  • 따라서 Junit에서 예외처리 에러를 던지기 위해서는 Service안에 예외처리를 만들어 줘야 하는 것이다

3. 해결방법

Service

    public PostCreateResponse postCreate(PostCreateRequest postCreateRequest, String userName){

        User user = userException.optionalUserDBCheck(userName)
                .orElseThrow(() -> new AppException(ErrorCode.USERNAME_NOT_FOUND,String.format("해당 유저가 없습니다.")));

        Post post = postRepository.save(postCreateRequest.toEntity(user));  // Post DB에 유저가 입력한 제목,내용 저장

        if(post == null){
            return PostCreateResponse.error();      // DB에서 오류가 발생하여 post값을 받아오지 못하면 "저장실패" 오류 출력
        }else {
            return PostCreateResponse.success(post.getId());    // 정상동작시 "등록 완료" 출력
        }
    }

Exception

    public Optional<User> optionalUserDBCheck(String userName){
        return userRepository.findByUserName(userName);
    }

Junit

    @Test
    @DisplayName("1. 포스트 등록 실패 - 로그인 안함")
    void postCreate_fail(){

        when(userException.optionalUserDBCheck(userName))
                    .thenReturn(Optional.empty());           // userName을 통해 DB에서 해당 데이터를 찾았지만 없을 경우 상황 설정
        when(postRepository.save(any()))
                    .thenReturn(PostEntityFixture.postEntity("han","1234"));    // 포스트 데이터 저장

        PostCreateRequest request = new PostCreateRequest(title,body);

        AppException exception = Assertions.assertThrows(AppException.class,() -> postService.postCreate(request,userName));        // userName을 통해 찾은 데이터가 없으므로 예외처리가 발생함
        assertEquals(ErrorCode.USERNAME_NOT_FOUND, exception.getErrorCode());
    }

  • 위 처럼 Service에서 예외처리를 해주기 위해 Exception에서는 Optional을 통해 DB에서 데이터만 찾고 Service에서 해당 내용에 대한 예외처리를 해주었다.
  • 이렇게 리팩토링 해주니 Test도 정상적으로 실행되는 것을 확인할 수 있었다.

4. 한줄 평가

  • Junit에서 테스트 할때는 Service에서 예외처리가 있어야 한다.
profile
Web Developer

0개의 댓글