Mock이란 어떤 행동을 했을 때 어떤 결과값을 줄 건지 정의한 가짜 객체를 뜻하며, Mockito는 Mock을 이용하여 테스트 코드를 작성할 수 있게 해주는 프레임워크이다.
아래 AddressController 파일이 있고 그 안에는 addrSave() 함수로 주소를 저장하는 Service 함수가 실행된다.
@RestController
@RequiredArgsConstructor
public class AddressController {
private final AddressService addressService;
@PostMapping("/v1/members/{id}/address")
public AddressResponse addrSave(@PathVariable("id") Long memberId,
@RequestBody CreateAddressRequest createAddressRequest) {
return addressService.addrSave(memberId, createAddressRequest);
}
}
Mockito 이용하여 단위테스트 적용 방법
단위테스트를 적용해 실제로 addressService.addrSave() 함수가 실행되게 하지 않고 가짜 객체를 만들어서 addrSave() 함수를 실제로 실행 안 시키게 하였다.
class AddressControllerUnitTest {
@DisplayName("회원 배송지 저장 단위 테스트")
@Test
void testAddrSave() {
//given
AddressService addressService = Mockito.mock(AddressService.class);
AddressResponse addressResponse = Mockito.mock(AddressResponse.class);
AddressController addressController = new AddressController(addressService);
//Mockito.when() -> given(), Mockito.thenReturn() -> willReturn()
BDDMockito.given(addressService.addrSave(Mockito.anyLong(), Mockito.any(CreateAddressRequest.class)))
.willReturn(addressResponse);
//when
addressResponse = addressController.addrSave(212L, new CreateAddressRequest());
//then
Mockito.verify(addressService, Mockito.times(1))
.addrSave(Mockito.anyLong(), Mockito.any(CreateAddressRequest.class));
}
}
위 코드에서 Mockito.mock(AddressService.class)로 AddressService 클래스를 가짜 객체로 만들었다. 그리고 그걸 AddressController 클래스에 주입하였다.
BDDMockito.given() 함수로 addressService.addrSave() 함수를 실행시키면 willReturn() 함수로 addressResponse 객체가 나오도록 지정하였다.
BDDMockito는 Mockito 클래스를 상속받아서 이름만 바꿔놓은 것인데 given, when, then을 적용한 BDD 스타일로 바꿔 놓은 것이다.
Mockito에서 when()은 given(), thenReturn()은 willReturn()이다.
위 코드에서 addressService.addrSave(Long타입, CreateAddressRequest 객체)함수를 실행시키면 addressResponse 객체를 리턴하겠다는 실행을 정의한 것이다. 이것이 mock객체에 대한 행위를 지정한 것이며 이걸 stub 또는 stubbing이라고 한다.
Mockito.verify()로 addrSave() 함수가 한번 실행이 되었는지 검증을 하였다.
@Mock, @InjectMocks 어노테이션 이해하기
이제 저걸 어노테이션 형태로 바꿔 보겠다. 우선 @Mock, @InjectMocks를 사용하려면 @ExtendWith(MockitoExtension.class)를 붙여야 한다.
Mockito.mock()으로 만들었던 가짜 객체를 @Mock으로 만들었고, 가짜객체를 주입받았던 AddressController를 @InjectMocks로 만들었다. @InjectMock은 가짜로 만든 객체를 주입하겠다는 뜻이다.
@ExtendWith(MockitoExtension.class)
class AddressControllerUnitTest {
@Mock
AddressService addressService;
@Mock
AddressResponse addressResponse;
@InjectMocks
AddressController addressController;
@DisplayName("회원 배송지 저장 단위 테스트")
@Test
void testAddrSave() {
//given
BDDMockito.given(addressService.addrSave(Mockito.anyLong(), Mockito.any(CreateAddressRequest.class)))
.willReturn(addressResponse);
//when
addressResponse = addressController.addrSave(212L, new CreateAddressRequest());
//then
Mockito.verify(addressService, Mockito.times(1))
.addrSave(Mockito.anyLong(), Mockito.any(CreateAddressRequest.class));
}
}
'Project > B2C-Side-Project(first)' 카테고리의 다른 글
[SpringBoot]GlobalException 활용한 코드 리팩토링 (0) | 2024.04.14 |
---|---|
[SpringBoot] 스프링 시큐리티 DB에서 사용자 정보 가져와서 로그인, 권한 적용 해보기 (1) | 2024.03.31 |
[SpringBoot] 스프링 시큐리티 설정 주의할점 (1) | 2024.03.29 |
[SpringBoot] Mysql boolean필드와 Java 멤버 필드 boolean 타입 매핑 주의 할점 (0) | 2024.03.24 |
[SpringBoot] Gradle 빌드툴에서 Swagger 적용 방법과 기본적인 문서 적용 방법 (0) | 2024.03.22 |