Day18 미션
1. @Mock, @MockBean, @Spy, @SpyBean, @InjectMocks 의 차이를 한번 정리해 봅시다.
2. 아래 3개의 테스트가 있습니다. 내용을 살펴보고, 각 항목을 @BeforeEach, given절, when절에 배치한다면 어떻게 배치하고 싶으신가요?(@BeforeEach에 올라간 내용은 공통 항목으로 합칠 수 있습니다. ex. 1-1과 2-1을 하나로 합쳐서 @BeforeEach에 배치)
"@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
검증
}"
1) @Mock, @MockBean, @Spy, @SpyBean, @InjectMocks 의 차이 정리
- @Mock vs @MockBean
- Mock은 단위 테스트, MockBean은 통합 테스트 시에 사용
- Mock은 순수한 Mockito 객체, MockBean은 Spring Bean을 Mocking할 때 사용
- Mock은 주입받으려면 @InMocks를 사용, MockBean은 @Autowired로 자동 주입
- Mock은 SpringContext와 무관, MockBean은 SpringContext에서 관리
- MockBean은 각 테스트 클래스에서 실행될 때마다 서버가 새로 뜬다.
- Mock은 service 단에서 repository를 mocking할 때 사용, MockBean은 controller 단에서 service를 mocking할 때 사용 (@WebMvcTest에서는 실제 빈을 주입하여야 하기 때문에 MockBean을 사용해야 함)
- when()을 사용해서 given 값 관리
- @Spy vs @SpyBean
- Spy는 실제 객체의 메서드를 호출하면서, 특정 메서드만 mocking할 수 있다.
- SpyBean도 Spy의 기능과 같지만, MockBean과 동일하게 Spring Context에서 관리한다는 차이점이 있다.
- doreturn()을 사용해서 given 관리
- @InjectMocks
- 순수한 Mockito 객체를 자동으로 주입할 때 사용
- @Mock과 @Spy를 주입해야 하는 객체에 사용
2) 각 항목을 @BeforeEach, given절, when절에 배치한다면 어떻게 배치하고 싶으신가요?
사용자 생성과 게시물 생성에 필요한 내용이 겹칠 경우
- 겹치는 내용이라면 중복 코드를 없앨 수 있고, 초기 설정값들이 공통되므로 인식하는데도 불편함이 없을 것 같다.
@BeforeEach
void setUp() {
1-1, 2-1, 3-1. 사용자1 생성에 필요한 내용 준비
1-2, 2-2, 3-2. 사용자1 생성
1-3, 2-3, 3-5. 사용자1의 게시물 생성에 필요한 내용 준비
1-4, 2-4, 3-6. 사용자1의 게시물 생성
}
@DisplayName("사용자가 댓글을 작성할 수 있다.")
@Test
void writeComment() {
// given
1-5. 댓글 생성에 필요한 내용 준비
// when
1-6. 댓글 생성
// then
검증
}
@DisplayName("사용자가 댓글을 수정할 수 있다.")
@Test
void updateComment() {
// given
2-5. 댓글 생성에 필요한 내용 준비
2-6. 댓글 생성
// when
2-7. 댓글 수정
// then
검증
}
@DisplayName("자신이 작성한 댓글이 아니면 수정할 수 없다.")
@Test
void cannotUpdateCommentWhenUserIsNotWriter() {
// given
3-3. 사용자2 생성에 필요한 내용 준비
3-4. 사용자2 생성
3-7. 사용자1의 댓글 생성에 필요한 내용 준비
3-8. 사용자1의 댓글 생성
// when
3-9. 사용자2가 사용자1의 댓글 수정 시도
// then
검증
}
사용자 생성과 게시물 생성에 필요한 내용이 겹치지 않고, 각 테스트마다 고유할 경우
- 각 테스트마다 고유한 내용이라면 분리하여, 독립성을 유지하는 게 맞다.
- 3번째 테스트에서는 사용자를 2번 생성하기에 코드 가독성 수준에서도 아래가 더 맞는 것 같다.
@BeforeEach
void setUp() {
// 레포지토리 초기화
}
@DisplayName("사용자가 댓글을 작성할 수 있다.")
@Test
void writeComment() {
// given
1-1. 사용자 생성에 필요한 내용 준비
1-2. 사용자 생성
1-3. 게시물 생성에 필요한 내용 준비
1-4. 게시물 생성
1-5. 댓글 생성에 필요한 내용 준비
// when
1-6. 댓글 생성
// then
검증
}
@DisplayName("사용자가 댓글을 수정할 수 있다.")
@Test
void updateComment() {
// given
2-1. 사용자 생성에 필요한 내용 준비
2-2. 사용자 생성
2-3. 게시물 생성에 필요한 내용 준비
2-4. 게시물 생성
2-5. 댓글 생성에 필요한 내용 준비
2-6. 댓글 생성
// when
2-7. 댓글 수정
// then
검증
}
@DisplayName("자신이 작성한 댓글이 아니면 수정할 수 없다.")
@Test
void cannotUpdateCommentWhenUserIsNotWriter() {
// given
3-1. 사용자1 생성에 필요한 내용 준비
3-2. 사용자1 생성
3-3. 사용자2 생성에 필요한 내용 준비
3-4. 사용자2 생성
3-5. 사용자1의 게시물 생성에 필요한 내용 준비
3-6. 사용자1의 게시물 생성
3-7. 사용자1의 댓글 생성에 필요한 내용 준비
3-8. 사용자1의 댓글 생성
// when
3-9. 사용자2가 사용자1의 댓글 수정 시도
// then
검증
}
[출처]
'인프런 워밍업 클럽 3기 BE 클린코드 & 테스트' 카테고리의 다른 글
[인프런 워밍업 클럽 BE 3기 클린코드 & 테스트] Day16 미션 (0) | 2025.03.28 |
---|---|
[인프런 워밍업 클럽 BE 3기 클린코드 & 테스트] Day4 미션 (3) | 2025.03.07 |
[인프런 워밍업 클럽 BE 3기 클린코드 & 테스트] Day 2 미션 (2) | 2025.03.04 |