BE 클린코드, 테스트코드 스터디 - Day 18 미션

1. @Mock, @MockBean, @Spy, @SpyBean, @InjectMocks 의 차이를 한번 정리해 봅시다.

2. 아래 3개의 테스트가 있습니다.

내용을 살펴보고, 각 항목을 @BeforeEach, given절, when절에 배치한다면 어떻게 배치하고 싶으신가요? (@BeforeEach에 올라간 내용은 공통 항목으로 합칠 수 있습니다. ex. 1-1과 2-1을 하나로 합쳐서 @BeforeEach에 배치)

<aside>

✅ 게시판 게시물에 달리는 댓글을 담당하는 Service Test ✅ 댓글을 달기 위해서는 게시물과 사용자가 필요하다. ✅ 게시물을 올리기 위해서는 사용자가 필요하다.

</aside>

@BeforeEach 
void setUp() {
    ❓
} 

@DisplayName(""사용자가 댓글을 작성할 수 있다."")
@Test
void writeComment() {
    1-1. 사용자 생성에 필요한 내용 준비
    1-2. 사용자 생성
    1-3. 게시물 생성에 필요한 내용 준비
    1-4. 게시물 생성
    1-5. 댓글 생성에 필요한 내용 준비
    1-6. 댓글 생성

    // given
    ❓

    // when
    ❓

    // then
    검증
}

@DisplayName(""사용자가 댓글을 수정할 수 있다."")
@Test
void updateComment() {
    2-1. 사용자 생성에 필요한 내용 준비
    2-2. 사용자 생성
    2-3. 게시물 생성에 필요한 내용 준비
    2-4. 게시물 생성
    2-5. 댓글 생성에 필요한 내용 준비
    2-6. 댓글 생성
    2-7. 댓글 수정

    // given
    ❓

    // when
    ❓

    // then
    검증
}

@DisplayName(""자신이 작성한 댓글이 아니면 수정할 수 없다."")
@Test
void cannotUpdateCommentWhenUserIsNotWriter() {
    3-1. 사용자1 생성에 필요한 내용 준비
    3-2. 사용자1 생성
    3-3. 사용자2 생성에 필요한 내용 준비
    3-4. 사용자2 생성
    3-5. 사용자1의 게시물 생성에 필요한 내용 준비
    3-6. 사용자1의 게시물 생성
    3-7. 사용자1의 댓글 생성에 필요한 내용 준비
    3-8. 사용자1의 댓글 생성
    3-9. 사용자2가 사용자1의 댓글 수정 시도

    // given
    ❓

    // when
    ❓

    // then
    검증        
}"

처음엔 코드를 보자마자 중복을 제거하고싶다는 생각이 마구 들었지만 자칫 중복만 제거해서는 코드를 읽는사람으로 하여금 맥락을 파악하기 어려울것 같다는 생각이 들었다. 테스트코드의 맥락 파악을 중점으로 작성해 보았다.

@BeforeEach 
void setUp() {
    사용자 생성에 필요한 내용 준비
    사용자 생성
    
    게시물 생성에 필요한 내용 준비
    게시물 생성
} 

그래서 setUp 메서드의 본질에 맞게 중복을 제거하기 보다는 테스트에 필요한 요소들을 설정해주었다. 3개의 테스트 모두 사용자와 댓글에 대한 테스트이므로 게시물과는 관련이 없으니 테스트할때마다 게시물을 생성해 줄 것이다. 그러기 위해선 사용자생성을 먼저 하고 게시물을 생성해 주었다.

@DisplayName(""사용자가 댓글을 작성할 수 있다."")
@Test
void writeComment() {

    // given
    사용자1 생성에 필요한 내용 준비
    사용자1 생성
    댓글 생성에 필요한 내용 준비

    // when
	  댓글 생성

    // then
    검증
}

setUp에서 사용자를 생성해주었지만 이 테스트에서 따로 사용자1을 생성한 이유는 setUp의 사용자는 게시물 생성을 위한 용도로 만든 사용자이고 이 테스트와는 전혀 무관하다. 또한 게시물의 작성자가 아니어도 댓글을 생성할수 있다는 정보도 알려줄 수 있다.

@DisplayName(""사용자가 댓글을 수정할 수 있다."")
@Test
void updateComment() {

  

    // given
    사용자1 생성에 필요한 내용 준비
    사용자1 생성
    댓글 생성에 필요한 내용 준비
    댓글 생성

    // when
	  댓글 수정

    // then
    검증
}

두번째 테스트도 첫번째 테스트와 같은 맥락으로 작성하였다.