- 관심 상품 최저가 업데이트 Service 코드
- 테스트 코드
- ProductService의 updateProduct 메서드를 테스트하려면 ProductService 객체를 생성할 때 생성자로 ProductRepository, FolderRepository, ProductFolderRepository를 전달해줘야함.
- 하지만 전달하려해도 인터페이스들인데 어떻게 전달하지?
- 그리고 또 전달한다고 해도 updateProduct 메서드 내부의 productRepository.findById(id) 코드는 어떻게 처리하지? 라는 의문이 듦.
가짜 객체 ( Mock )
- 가짜 객체 (Mock object) 로 분리
- MockRepository
- 실제 객체와 겉만 같은 객체
- 동일한 클래스명, 함수명
- 실제 DB 작업은 하지 않음
- DB 작업이 이뤄지는 것처럼
- 테스트를 위해 필요한 결과값을 return
- 실제 객체와 겉만 같은 객체
- 간단히 'mock' (목) 이라고 부름
Mockito 를 사용한 단위테스트 구현
- Mockito framework: Mock 객체를 쉽게 만들 수 있는 방법 제공
@ExtendWith(MockitoExtension.class) // @Mock 사용을 위해 설정
class ProductServiceTest {
@Mock
ProductRepository productRepository;
@Mock
FolderRepository folderRepository;
@Mock
ProductFolderRepository productFolderRepository;
Long productId = 100L;
int myprice = ProductService.MIN_MY_PRICE + 3_000_000;
given(productRepository.findById(productId)).willReturn(Optional.of(product));
given 을 이용해서 위와 같이 필요한 값을 직접 뽑아서 넣어준다.
findById 는 기능을 하지 않지만 중요한 건 findById 가 아니라 update 를 하는 기능을 검사해야하는 것이기 때문에
findById 는 직접 given 을 사용해서 값만 가져와서 넣어준다.
앞으로도
Test 는 기능에 포커스를 두고 그 기능을 하는지 값을 가져오는데에 어떻게 가져올지 생각을 하면 될 것 같다.
Mockito 를 적용해 수정한 코드 수정본
더보기
@ExtendWith(MockitoExtension.class) // @Mock 사용을 위해 설정합니다.
class ProductServiceTest {
@Mock
ProductRepository productRepository;
@Mock
FolderRepository folderRepository;
@Mock
ProductFolderRepository productFolderRepository;
@Test
@DisplayName("관심 상품 희망가 - 최저가 이상으로 변경")
void test1() {
// given
Long productId = 100L;
int myprice = ProductService.MIN_MY_PRICE + 3_000_000;
ProductMypriceRequestDto requestMyPriceDto = new ProductMypriceRequestDto();
requestMyPriceDto.setMyprice(myprice);
User user = new User();
ProductRequestDto requestProductDto = new ProductRequestDto(
"Apple <b>맥북</b> <b>프로</b> 16형 2021년 <b>M1</b> Max 10코어 실버 (MK1H3KH/A) ",
"https://shopping-phinf.pstatic.net/main_2941337/29413376619.20220705152340.jpg",
"https://search.shopping.naver.com/gate.nhn?id=29413376619",
3515000
);
Product product = new Product(requestProductDto, user);
ProductService productService = new ProductService(productRepository, folderRepository, productFolderRepository);
given(productRepository.findById(productId)).willReturn(Optional.of(product));
// when
ProductResponseDto result = productService.updateProduct(productId, requestMyPriceDto);
// then
assertEquals(myprice, result.getMyprice());
}
@Test
@DisplayName("관심 상품 희망가 - 최저가 미만으로 변경")
void test2() {
// given
Long productId = 200L;
int myprice = ProductService.MIN_MY_PRICE - 50;
ProductMypriceRequestDto requestMyPriceDto = new ProductMypriceRequestDto();
requestMyPriceDto.setMyprice(myprice);
ProductService productService = new ProductService(productRepository, folderRepository, productFolderRepository);
// when
Exception exception = assertThrows(IllegalArgumentException.class, () -> {
productService.updateProduct(productId, requestMyPriceDto);
});
// then
assertEquals(
"유효하지 않은 관심 가격입니다. 최소 " +ProductService.MIN_MY_PRICE + " 원 이상으로 설정해 주세요.",
exception.getMessage()
);
}
}
'컴퓨터 프로그래밍 > Spring' 카테고리의 다른 글
[Spring] AOP (0) | 2024.09.10 |
---|---|
[Spring] 통합 테스트 (1) | 2024.09.10 |
[Spring] 단위 테스트 프레임워크 JUnit5, Given-When-Then 패턴 (0) | 2024.09.09 |
[Spring] 인터페이스의 default 메서드 (0) | 2024.09.01 |
[Spring] RequestEntity (0) | 2024.08.30 |