코드 그라데이션

230217 BoardServiceImpl 테스트 코드 (2) 게시글 수정 성공 / 실패 본문

Spring/Test Code

230217 BoardServiceImpl 테스트 코드 (2) 게시글 수정 성공 / 실패

완벽한 장면 2023. 2. 26. 03:22

초안

 @Test
  @DisplayName("게시글 업데이트 성공 테스트")
  void updateBoard() {
  
    // given
    User user = mock(User.class);
    Board board = mock(Board.class);
    BoardRequestDto boardRequestDto = mock(BoardRequestDto.class);

    when(boardRepository.findById(board.getId())).thenReturn(Optional.of(board));
    when(Optional.of(board).get().checkBoardWriter(user)).thenReturn(true);
    // 이 두 줄은 깡통에게 "이런 질문이 오면 무조건 이렇게 대답해" 하고 명령을 넣어놓는 것.

    // when
    boardService.updateBoard(board.getId(), boardRequestDto, user);

    // then
    verify(board).update(boardRequestDto);
  }

 

부연설명

여기도 마찬가지
일단 내가 모르겠는 부분을 좀 보자

when(Optional.of(board).get().checkBoardWriter(user)).thenReturn(true);
이거

1. when(Optional.of(board)
2. .get().checkBoardWriter(user))
3. .thenReturn(true);
이렇게 뜻어볼 수 있음.

즉,
Optional<Board> board1 = Optional.of(board); //보드를 옵셔널로 감쌌다.
Board board2 = board1.get() //거기서 다시 보드를 얻었고
// 다시 감싼 걸 없앤 것. 즉, +5 후 -5 한 것이라고 생각하면 된다.
따라서
when(Optional.of(board).get().checkBoardWriter(user)).thenReturn(true); 자체를
when(board.get().checkBoardWriter(user)).thenReturn(true); 라고 써도 된다.

board2.checkBoardWriter(user);

// cf. 옵셔널은 객체를 한 번 감싼 것, 즉 객체가 null이라고 하더라도 감싼 것에 물어보니까
// 감싸고 있는 것은 절대 null이 아니기 때문에, nullPointException이 나지 않음.
지금 반환값이 void니까, assertThat으로 확인이 불가능하지.
그렇다면 board.update(boardRequestDto); 요 객체를 직접 확인해보는 방법을 쓰자.

그럼 board를 mocking 보다는 그냥 만들어주는게 테스트 확인에서는 더 보기 편안할 것 같아.
보드를 만들 때 필수요소인 title, content, subject는 반드시 있어야겠지.

  @Test
  @DisplayName("게시글 업데이트 성공 테스트")
  void updateBoard() {
    // given
    User user = mock(User.class);
    Board board = Board.builder()
            .title("test-title")
            .content("test-content")
            .subject(Board.BoardSubject.동네소식)
            .user(user)
            .build();
            
    // 그런데 테스트가 되려면 Dto까지 값이 있어야겠죠. 내가 확인하고 싶은 값이니까
    // title을 반드시 바꿔야해요.
    BoardRequestDto boardRequestDto = BoardRequestDto.builder()
            .title("after-title")
            .content("after-content")
            .subject(Board.BoardSubject.공지사항)
            .build();
    
    // 이건 잘 되어 있고,
    when(boardRepository.findById(board.getId())).thenReturn(Optional.of(board));
    
    // board는 이제 더이상 mock 객체가 아니므로 이 문장은 불가능해졌음
        // when(board.get().checkBoardWriter(user)).thenReturn(true);
    // 하지만 위에서 user을 넣어줬고, //when에서 똑같은 user을 업데이트 하라고 했기 때문에
    
        // when에서 이 식이 true로 정상적으로 잘 수행이 될 것이다.
    boardService.updateBoard(board.getId(), boardRequestDto, user);
    
    // 이제 then으로 확인만 해주면 됨.
        // then
    assertThat(board.getTitle()).isEqualTo(boardRequestDto.getTitle());
    assertThat(board.getContent()).isEqualTo(boardRequestDto.getContent());
    assertThat(board.getSubject()).isEqualTo(boardRequestDto.getSubject());

이제 게시글 수정 실패 테스트 코드

BoardServiceImpl 코드 중에
 if (!board.checkBoardWriter(user)) {
      throw new IllegalArgumentException("본인 게시글이 아닙니다");
    }
    
   	이 상황이 일어나게 만들면 된다!
    
    => 그렇게 되려면
    board가 가진 user와 요청을 보내는 user가 다르기면 하면 된다.
    
    여기서는 dto가 쓰이고 있긴 하지만, 이 테스트 자체는 board와 user에만 관심이 있는 것.
    이럴 때는 dto내용을 없애거나 mocking을 하거나 값을 null 주면 된다.
    
  @Test
  @DisplayName("게시글 업데이트 실패 테스트 : 본인 게시글이 아닌 경우")
  void updateBoard() {
    // given
    // 본인인지 아닌지 유저를 알아봐야하니까, just mocking 할 것이 아니라
    // user를 직접 만들어서 비교해주는게 맞다.
    // User user = mock(User.class);
    유저 하나를 만들어주고,
        // given
    User userA = User.builder()
            .username("userA")
            .password("password1")
            .build();
            
	얘랑 다른 사용자 하나를 더 만들어 줘야 같은 사람이 아님을 비교할 수 있겠지.
    User userB = User.builder()
            .username("userB")
            .password("password2")
            .build();

    게시글 생성 때는 UserA를 주고
    Board board = Board.builder()
            .title("test-title")
            .content("test-content")
            .subject(Board.BoardSubject.동네소식)
            .user(userA)
            .build();
    
    when(boardRepository.findById(board.getId())).thenReturn(Optional.of(board);
    
    /*
    //when
    업데이트 할 때는 userB를 준다
    boardService.updateBoard(board.getId(), null, userB);
    
    => 여기까지 하면 "본인 게시글이 아닙니다" 메시지 뜨고 터지고 끝난다.
    */
    예외처리 해줘야지
    따라서 이렇게 수정해준다
     // when
    assertThatThrownBy(() -> {

      boardService.updateBoard(board.getId(), null, userB); //예외가 발생하는 코드 삽입

    }).isInstanceOf(IllegalArgumentException.class); // 결과. then
  }

최종본

  @Test
  @DisplayName("게시글 업데이트 성공 테스트")
  void updateBoard() {
    // given
    User user = mock(User.class);
    Board board = Board.builder()
            .title("test-title")
            .content("test-content")
            .subject(Board.BoardSubject.동네소식)
            .user(user)
            .build();

    BoardRequestDto boardRequestDto = BoardRequestDto.builder()
            .title("after-title")
            .content("after-content")
            .subject(Board.BoardSubject.공지사항)
            .build();

    when(boardRepository.findById(board.getId())).thenReturn(Optional.of(board));

    // when
    boardService.updateBoard(board.getId(), boardRequestDto, user);

    // then
    assertThat(board.getTitle()).isEqualTo(boardRequestDto.getTitle());
    assertThat(board.getContent()).isEqualTo(boardRequestDto.getContent());
    assertThat(board.getSubject()).isEqualTo(boardRequestDto.getSubject());
//    verify(board).update(boardRequestDto);
  }

  @Test
  @DisplayName("게시글 업데이트 실패 테스트: 본인 게시글이 아닌 경우")
  void failsUpdateBoard() {
    // given
    User userA = User.builder()
            .username("userA")
            .password("password1")
            .build();

    User userB = User.builder()
            .username("userB")
            .password("password2")
            .build();

    Board board = Board.builder()
            .title("test-title")
            .content("test-content")
            .subject(Board.BoardSubject.동네소식)
            .user(userA)
            .build();

    when(boardRepository.findById(board.getId())).thenReturn(Optional.of(board));

    // when
    assertThatThrownBy(() -> {

      boardService.updateBoard(board.getId(), null, userB);

    }).isInstanceOf(IllegalArgumentException.class);
  }

 

-1:13

728x90
Comments