[워밍업 클럽 4기 - 백엔드] Day18 미션
[인프런 워밍업 클럽 스터디 4기 - 백엔드]
강의 출처 :
Readable Code: 읽기 좋은 코드를 작성하는 사고법
Practical Testing: 실용적인 테스트 가이드
Day18 미션 1 :
Mockito 어노테이션 (@Mock, @MockBean, @Spy, @SpyBean, @InjectMocks) 차이점 정리하기.
@Mock
Mockito에서 사용하는 어노테이션으로, 테스트 코드 안에서 가짜 객체를 만들어줌
실제 객체처럼 사용할 수 있지만, 내부 동작은 하지 않고 필요한 동작만 지정해서 사용함
Mockito 단독으로 사용할 때는 설정이 필요함
스프링 환경과는 무관하고, 순수한 단위 테스트에서 많이 사용됨
@MockBean
스프링 테스트 환경에서 mock 객체를 등록할 때 사용하는 어노테이션
기존에 스프링 빈으로 등록돼 있는 객체를 mock 객체로 바꿔서 테스트에 사용함
@SpringBootTest 나 @WebMvcTest 같이 스프링 컨텍스트를 여는 테스트에서 사용 가능
자동으로 스프링 컨테이너에 등록되고, @Autowired 같은 방식으로 주입됨
@Spy
진짜 객체를 감싸서 사용하는 Test Double
원래 동작은 유지하면서, 필요한 일부만 Stubbing 해서 바꿔 쓸 수 있음
mock보다 실제 객체에 더 가까운 형태라, 상태를 함께 확인하거나 부분 제어가 필요한 경우에 사용
@Mock과 마찬가지로 @ExtendWith(MockitoExtension.class)가 필요함
@SpyBean
스프링 테스트 환경에서 사용하는 @Spy 형태
기존 스프링 빈을 spy로 등록하고, 진짜 동작은 유지하면서 필요한 부분만 바꿔서 사용할 수 있음
인터페이스에 적용할 경우, 구현체가 반드시 컨테이너에 등록돼 있어야 오류가 나지 않음
테스트 중 일부 메서드는 실제로 실행하고, 일부는 stubbing 하고 싶을 때 사용할 수 있음
@InjectMocks
@Mock이나 @Spy로 만든 객체들을 주입받는 테스트 대상 클래스에 붙이는 어노테이션
생성자, 필드, setter 등을 통해 적절한 위치에 의존성을 자동으로 넣어줌
테스트 대상 객체를 직접 생성하지 않아도 되고, mock 객체들로 알아서 조립해주는 역할
이 어노테이션만으로는 동작하지 않고, @Mock이나 @Spy가 함께 있어야 의미가 있음
Day18 미션 2 :
테스트의 각 항목을 @BeforeEach, given절, when절에 배치해보기.
[수정한 코드]
@BeforeEach
void setUp() {
사용자 생성에 필요한 내용 준비 (1-1, 2-1, 3-1)
사용자 생성 (1-2, 2-2, 3-2)
게시물 생성에 필요한 내용 준비 (1-3, 2-3, 3-5)
게시물 생성 (1-4, 2-4, 3-6)
}
@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
검증
}
[해결 과정]
댓글에 관한 테스트가 목적이기 때문에, 댓글 작성 전에 사용자와 게시물이 먼저 생성되어 있어야 하는 구조라고 판단하여 공통적으로 필요한 사용자 및 게시물 생성을 @BeforeEach에 넣었습니다.
첫 번째 테스트는 댓글의 작성이 핵심 동작으로, 댓글 생성 전 필요한 과정을 given, 실제 생성을 when에 배치했습니다.
두 번째 테스트는 이미 작성된 댓글을 수정하는 상황이기 때문에, given에 댓글 생성까지 포함하고, when에서는 수정 동작만 수행했습니다.
세 번째 테스트는 댓글 작성자가 아닌 사용자가 수정 시도하는 경우이므로, given에서 별도의 사용자와 댓글을 생성한 후, when에 타인의 댓글을 수정하는 동작을 넣었습니다.
댓글을 작성해보세요.