[워밍업 클럽 2기] Day 18 - 모킹 애노테이션의 종류, 테스트 내용 배치
워밍업 클럽 2기: Clean Code & Test Code의 Day 18 미션입니다.
🎯 미션 1
1. @Mock
, @MockBean
, @Spy
, @SpyBean
, @InjectMocks
의 차이를 한번 정리해 봅시다.
@Mock
Mockito의 기본 모킹 애너테이션
Mock 객체를 만들어 해당 객체의 메서드 호출에 대해 미리 정의된 값을 반환하도록 설정 가능(stub)
Mock 객체는 실제 메서드를 호출하지 않고 동작만 시뮬레이션 한다
@MockBean
Mock 객체를 빈으로 등록합니다. 이는 테스트 대상 클래스가 의존성 주입을 통해 해당 Mock 빈을 받을 수 있도록한다.
보통
@SpringBootTest
나@WebMvcTest
와 같은 Spring 컨텍스트와 함께 사용되는 경우에 적합하다
@Spy
Mockito에서 객체의 일부 메서드만 모킹하고 나머지는 실제 메서드를 호출할 수 있다
객체의 일부 기능만 변경하여 테스트하고 싶은 경우 사용한다
실제 객체가 만들어져서 사용된다
doReturn().when.()
사용
SpyBean
부분 모킹을 위해 스프링 컨텍스트에 등록된 실제 빈을 Spy로 대체한다
실제 빈의 일부 메서드만 모킹하고, 나머지는 실제 메서드를 호출하게 할 때 유용하다
@InjectMocks
테스트 클래스에 정의된
@Mock
또는@Spy
로 선언된 객체를 주입하여, 대상 클래스의 의존성을 자동으로 설정한다
🎯 미션 2
2. 아래 3개의 테스트가 있습니다. 내용을 살펴보고, 각 항목을 @BeforeEach
, given절, when절에 배치한다면 어떻게 배치하고 싶으신가요? (@BeforeEach
에 올라간 내용은 공통 항목으로 합칠 수 있습니다. ex. 1-1과 2-1을 하나로 합쳐서 @BeforeEach
에 배치)
As-Is
@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 - 검증
}
다음은 미션을 수행한 To-Be 입니다.
To-Be
@BeforeEach
void setUp() {
1-1. 사용자 생성에 필요한 내용 준비, 2-1. 사용자 생성에 필요한 내용 준비,
3-1. 사용자1 생성에 필요한 내용 준비
3-3. 사용자2 생성에 필요한 내용 준비
1-3. 게시물 생성에 필요한 내용 준비, 2-3. 게시물 생성에 필요한 내용 준비,
3-5. 사용자1의 게시물 생성에 필요한 내용 준비
}
@DisplayName("사용자가 댓글을 작성할 수 있다.")
@Test
void writeComment() {
// given
1-2. 사용자 생성
1-4. 게시물 생성
1-5. 댓글 생성에 필요한 내용 준비
// when
1-6. 댓글 생성
// then - 검증
}
@DisplayName(""사용자가 댓글을 수정할 수 있다."")
@Test
void updateComment() {
// given
2-2. 사용자 생성
2-4. 게시물 생성
2-5. 댓글 생성에 필요한 내용 준비
2-6. 댓글 생성
// when
2-7. 댓글 수정
// then - 검증
}
@DisplayName("자신이 작성한 댓글이 아니면 수정할 수 없다.")
@Test
void cannotUpdateCommentWhenUserIsNotWriter() {
// given
3-2. 사용자1 생성
3-4. 사용자2 생성
3-6. 사용자1의 게시물 생성
3-7. 사용자1의 댓글 생성에 필요한 내용 준비
3-8. 사용자1의 댓글 생성
// when
3-9. 사용자2가 사용자1의 댓글 수정 시도
// then - 검증
}
고려한 내용
@BeforeEach()
에는 각 테스트에서 반복되지만, 검증하는 대상과는 직접적인 관련이 없는 공통 준비 사항을 처리하려고 했다. 여기서 준비하는 내용은 없어도 각 테스트를 이해할 수 있어야 하고, 각 내용이 변경되어도 각 테스트는 정상적으로 수행될 수 있어야 한다.when
에는 각 테스트에서 검증하는 행위만을 배치시켰다
🔍 참고
댓글을 작성해보세요.