이번 포스팅에선 Mockito 설정하는 방법과 mock 객체 생성관련 어노테이션에 대해 알아보겠습니다.
Mockito 설정
mockito 최신 버전은 jcenter에 올라와있으니 설정한 후에 의존성을 추가하면 됩니다.
repositories { jcenter() }
// maven
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-android</artifactId>
<version>3.7.7</version>
<type>pom</type>
</dependency>
// gradle
implementation 'org.mockito:mockito-android:3.7.7'
라이브러리 설정 후 Mockito를 사용하려면 테스트 클래스 위에 @ExtendWith(MockitoExtension.class)를 붙혀줘야합니다.
@ExtendWith(MockitoExtension.class)
public class mockCreate {
//...
}
Mock 생성
mock 생성 관련된 어노테이션은 @Mock, @Spy, @InjectMock 이 있습니다. 하나씩 설명하겠습니다.
@Mock
@Mock으로 만든 mock 객체는 가짜 객체이며 그 안에 메소드 호출해서 사용하려면 반드시 스터빙(stubbing)을 해야합니다. (스터빙은 아래에서 자세히 다루겠습니다.)
만약, 스터빙을 하지 않고 그냥 호출한다면 primitive type은 0, 참조형은 null을 반환합니다.
예제
테스트를 위해 아래와 같은 UserService를 만들었습니다.
public class UserService {
public User getUser() {
return new User("effortguy", "1234");
}
public int getLoginErrNum() {
return 1;
}
}
@Mock을 사용하고 스터빙을 하지 않으니 레퍼런스 타입은 null, primitive type은 0을 반환합니다.
@ExtendWith(MockitoExtension.class)
public class MockAnnotation {
@Mock
UserService userService;
@Test
void testReferenceType() {
assertNull(userService.getUser());
}
@Test
void testPrimitiveType() {
assertEquals(0, userService.getLoginErrNum());
}
}
@Spy
@Spy로 만든 mock 객체는 진짜 객체이며 메소드 실행 시 스터빙을 하지 않으면 기존 객체의 로직을 실행한 값을, 스터빙을 한 경우엔 스터빙 값을 리턴합니다.
예제
테스트를 위해 아래와 같은 ProductService를 만들었습니다.
public class ProductService {
public Product getProduct() {
return new Product("A001", "monitor");
}
}
스터빙을 안 한 테스트는 기존 객체의 로직을, 스터빙을 한 테스트는 스터빙 값을 리턴하는 것을 볼 수 있습니다.
@ExtendWith(MockitoExtension.class)
public class SpyAnnotation {
@Spy
ProductService productService;
@Test
void testSpy_스터빙X() {
Product product = productService.getProduct();
assertEquals("A001", product.getSerial());
}
@Test
void testSpy_스터빙O() {
Product productDummy = new Product("B001", "keyboard");
when(productService.getProduct()).thenReturn(productDummy);
Product product = productService.getProduct();
assertEquals(productDummy.getSerial(), product.getSerial());
}
}
@InjectMock
@InjectMock은 DI를 @Mock이나 @Spy로 생성된 mock 객체를 자동으로 주입해주는 어노테이션입니다.
예제
@Mock, @Spy 예제에서 만들었던 UserService, ProductService를 주입받아 사용하는 OrderService를 만들었습니다.
public class OrderService {
UserService userService;
ProductService productService;
OrderService(UserService userService, ProductService productService) {
this.userService = userService;
this.productService = productService;
}
public User getUser() {
return userService.getUser();
}
public Product getProduct() {
return productService.getProduct();
}
}
@InjectMocks를 사용하니@Mock, @Spy로 만든 객체들이 자동으로 주입된 것을 볼 수 있습니다.
@ExtendWith(MockitoExtension.class)
public class InjectMocksAnnotation {
@Mock
UserService userService;
@Spy
ProductService productService;
@InjectMocks
OrderService orderService;
@Test
void testGetUser() {
assertNull(orderService.getUser());
}
@Test
void testGetProduct() {
Product product = orderService.getProduct();
assertEquals("A001", product.getSerial());
}
}
@InjectMocks을 쓴 객체의 mock 객체를 주입 받을 수 있는 형태는 Constructor, Property Setter, Field Injection이 있습니다.
이전에 DI 관련 정리를 한 것이 있으니 참고하시길 바랍니다.
Mockito 공식 홈페이지 @InjecMocks 설명도 있으니 참고하시길 바랍니다.
다음 포스팅에선 mock 객체의 스터빙(Stubbing), 검증(Verify)에 대해서 알아보겠습니다.
읽어주셔서 감사합니다.
'Java' 카테고리의 다른 글
[Java] Mockito 사용법 (4) - 검증 (Verify) (0) | 2022.09.06 |
---|---|
[Java] Mockito 사용법 (3) - 스터빙 (Stubbing) (OngoingStubbing, Stubber) (0) | 2022.09.06 |
[Java] Mockito 사용법 (1) - Mock이란?, Mockito 소개 (1) | 2022.09.06 |
[Java] Apache Log4j 2.x 취약점 및 해결 방법 (Log4j2 remote code execution vulnerability) (8) | 2021.12.12 |
[Java] equals(), hashCode(), toString() 재정의 이유와 방법 (2) (0) | 2021.04.16 |
댓글