인프런 워밍업 스터디 클럽 2기 백엔드(클린코드&테스트코드) Day 18 미션

인프런 워밍업 스터디 클럽 2기 백엔드(클린코드&테스트코드) Day 18 미션

인프런 워밍업 클럽 2기, 백엔드(클린코드&테스트코드) 과정에 참여하고 있습니다.

이번 글은 Day 18 미션 제출을 위해 작성하였습니다.

[미션 내용]

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

  2. 미션에서 제공된 예제를 살펴보고, 각 항목을 @BeforeEach, given절, when절에 배치해보기

     

강의 링크: Readable Code: 읽기 좋은 코드를 작성하는 사고법


 

1. Test Double Annotations 특징

  • @Mock

    • 실제 객체 대신 가짜 객체를 생성한다.

      • 기본적으로 모든 메서드가 아무런 동작도 하지 않음.

    • when() 을 통해 특정 메서드의 동작과 결과값을 임의로 지정할 수 있음.

    • Spring context 의존 X.

@Mock
private UserService userService;

// 사용 예시
when(userService.findById(1L)).thenReturn(new User());
  • @MockBean

    • 기본적으로 @Mock 과 유사하지만, Spring context에 의존한다.

      • Spring context에 Mock 객체를 Bean으로 등록함.

      • 같은 타입의 기존 Bean을 찾아서 Mock으로 교체하는 방식

    • 통합 테스트에서 특정 Bean만 Mock으로 대체하고 싶을 때 유용함.

@MockBean
private UserService userService; 
  • @Spy

    • 실제 객체를 생성하고 일부 메서드만 Mock으로 지정할 수 있음.

      • 명시적으로 지정하지 않은 메서드는 실제 동작을 수행한다.

    • 일부 메서드만 수정하고 싶을 때 유용함.

@Spy
private UserService userService;

// 특정 메서드만 Mock 처리
doReturn(new User()).when(userService).findById(1L);
  • @SpyBean

    • 기본적으로 @Spy 와 유사하지만, Spring context에 의존한다.

      • Spring context의 실제 Bean을 Spy로 감싸서 사용함.

    • 실제 Bean 의 일부 동작만 수정하고 싶을 때 유용함.

       

@SpyBean
private UserService userService;
  • @InjectMocks

    • Spring context 의존 없이(통합 테스트 없이) 의존성 주입이 필요한 클래스(ex. Service class)를 테스트할 때 유용하다.

      • @Mock 이나 @Spy로 생성된 객체를 자동으로 주입받도록 해준다.

@Mock
private UserRepository userRepository;

@InjectMocks
private UserService userService;  // userRepository가 자동 주입됨

 

주요 차이점

  1. 통합 테스트 필요 여부 차이

    1. 필요: @MockBean, @SpyBean

    2. 불필요: @Mock, @Spy, @InjectMocks

  2. 동작 방식

    1. 완전한 가짜 객체: @Mock, @MockBean

    2. 실제 객체를 부분적으로 Mocking: @Spy, @SpyBean

 


 

@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
    검증        
}

 

댓글을 작성해보세요.

채널톡 아이콘