240220 TIL #326 Mock / Mockito

김춘복·2024년 2월 20일
0

TIL : Today I Learned

목록 보기
326/543
post-custom-banner

Today I Learned

오늘은 테스트에 이어 mock을 공부해보았다.


Mock Object

이상적으로 각 테스트 케이스는 서로 분리되어야 하지만 현실적으로 프로젝트 상에서 객체들이 이미 얽혀 있기 때문에(의존성) 이러한 상황에서 테스트를 하기 위해 Mock객체(가짜 객체)를 사용한다.

  • Mock 객체는 실제 객체와 겉만 같다. Mock Repository에선 실제 DB작업은 하지 않는다.
    Mock Repository에서 미리 설정해둔 더미 데이터만 반환하게 한다면 서비스 로직만들 배타적으로 테스트 할 수 있게 된다.

Mockito

Mock 객체를 편하게 만들고 관리해주는 라이브러리
Spring Boot 2.2+ 사용시 spring-boot-start-test에서 자동으로 Mokito를 추가해준다.
그 이전 버전 사용시 build.gradle의 dependencies에 아래 코드 삽입

	testImplementation 'org.mockito:mockito-core:4.8.0'
    testImplementation 'org.mockito:mockito-junit-jupiter:4.8.0'
  • Mock 실제 사용법 : Test 클래스 만들어서 사용
@ExtendWith(MockitoExtension.class)
class ProductServiceTest {
    @Mock //  (1)
    ProductRepository productRepository;

    @InjectMocks //  (2)
    ProductService productService;

    @Mock
    User user;


    @Test
    @DisplayName("관심 상품 희망가 - 최저가 이상으로 변경")
    void updateProduct_Success() {
    // given 부분
    Long userId = 777L;
    Product product = new Product(requestProductDto, userId);
    // 생략...
    
    // when 부분
    // user.getId()를 실행하면 given에서 설정한 userId를 반환
    when(user.getId())
            .thenReturn(userId);
    // repo에서 .findBy~를 실행하면 given에서 설정한 product를 반환
    when(productRepository.findByIdAndUserId(productId, userId))
            .thenReturn(Optional.of(product));
            
    // when, then
    assertDoesNotThrow( () -> {
        productService.updateProduct(productId, requestMyPriceDto, user);
	});
}

(1) : @Mock으로 모킹할 객체 표기. 필요한 객체들을 모킹
(2) : @InjectMocks로 모킹한 객체 주입. @InjectMocks이 붙은 서비스에는 @Mock이 붙은 가짜 repository와 User가 주입된다.
(3) : When() 메서드로 모킹한 객체들이 특정조건으로 특정 메서드를 호출하면 다음과 같이 동작하도록 지정해준다.

profile
Backend Dev / Data Engineer
post-custom-banner

0개의 댓글