From 0ad38034c89d01bb5bee80ecee3ad54ed0e47ba9 Mon Sep 17 00:00:00 2001 From: PARKJONGGYEONG Date: Tue, 14 May 2024 17:20:59 +0900 Subject: [PATCH 1/2] =?UTF-8?q?test:=20testcase=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ElasticCategoryServiceUnitTest.java | 117 +++++++++++++++++- .../service/ElasticServiceUnitTest.java | 96 ++++++++++++++ 2 files changed, 212 insertions(+), 1 deletion(-) diff --git a/src/test/java/com/t3t/bookstoreapi/elastic/service/ElasticCategoryServiceUnitTest.java b/src/test/java/com/t3t/bookstoreapi/elastic/service/ElasticCategoryServiceUnitTest.java index 7ecbcf94..af569788 100644 --- a/src/test/java/com/t3t/bookstoreapi/elastic/service/ElasticCategoryServiceUnitTest.java +++ b/src/test/java/com/t3t/bookstoreapi/elastic/service/ElasticCategoryServiceUnitTest.java @@ -1,14 +1,19 @@ package com.t3t.bookstoreapi.elastic.service; +import com.t3t.bookstoreapi.book.util.BookServiceUtils; import com.t3t.bookstoreapi.elastic.model.dto.ElasticDocument; import com.t3t.bookstoreapi.elastic.model.response.ElasticResponse; import com.t3t.bookstoreapi.elastic.repository.ElasticRepository; import com.t3t.bookstoreapi.model.response.PageResponse; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.Mockito; import org.springframework.data.domain.PageRequest; import org.springframework.data.elasticsearch.core.SearchHit; import org.springframework.data.elasticsearch.core.SearchHits; @@ -16,11 +21,14 @@ import org.springframework.test.context.junit.jupiter.SpringExtension; import java.math.BigDecimal; +import java.time.Instant; +import java.time.ZoneId; import java.util.ArrayList; import java.util.List; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.mockito.Mockito.when; +import static org.mockito.Mockito.*; +import static org.mockito.Mockito.mock; @ExtendWith(SpringExtension.class) public class ElasticCategoryServiceUnitTest { @@ -31,6 +39,17 @@ public class ElasticCategoryServiceUnitTest { @InjectMocks private ElasticCategoryService elasticService; + private static MockedStatic bookServiceUtilsMockedStatic; + + @BeforeAll + public static void before() { + bookServiceUtilsMockedStatic = mockStatic(BookServiceUtils.class); + } + @AfterAll + public static void after() { + bookServiceUtilsMockedStatic.close(); + } + @Test @DisplayName("엘라스틱서치 검색 기능 테스트") public void testSearch() { @@ -69,4 +88,100 @@ public void testSearch() { assertEquals("Test Book", elasticResponse.getName()); assertEquals(4.0f, elasticResponse.getAverageScore()); // 검증 } + @Test + @DisplayName("엘라스틱서치 검색 기능 테스트-null인 경우") + public void testSearchNull() { + // Given + String query = "test"; + String searchType = "book_name"; + BigDecimal categoryId = new BigDecimal("10"); + PageRequest pageable = PageRequest.of(0, 10); + + ElasticCategoryService elasticService = mock(ElasticCategoryService.class); + Mockito.lenient().when(elasticService.search(query, searchType, categoryId, pageable)).thenReturn(null); + + ElasticDocument document = mock(ElasticDocument.class); + Mockito.lenient().when(document.getCoverImageUrl()).thenReturn(null); + Mockito.lenient().when(document.getName()).thenReturn("Test Book"); + Mockito.lenient().when(document.getAverageScore()).thenReturn(4.0f); + + List> searchHitList = new ArrayList<>(); + searchHitList.add(new SearchHit<>(null, null, null, 1.0f, null, null, document)); + SearchHits searchHits = new SearchHitsImpl<>(1, null, 1.0f, null, searchHitList, null, null); + Mockito.lenient().when(elasticRepository.findByBookNameCategory(query, categoryId, pageable)).thenReturn(searchHits); + + // When + PageResponse response = elasticService.search(query, searchType, categoryId, pageable); + + // Then + if (response != null) { + ElasticResponse elasticResponse = response.getContent().get(0); + assertEquals("Test Book", elasticResponse.getName()); + assertEquals(4.0f, elasticResponse.getAverageScore()); + } + } + + @Test + @DisplayName("엘라스틱서치 검색 결과 응답 객체 생성 테스트") + public void testBuildElasticSearchResultResponse() { + // Given + ElasticDocument document = new ElasticDocument(); + document.setBookId(BigDecimal.ONE); + document.setName("Test Book"); + document.setPrice(BigDecimal.valueOf(100)); + document.setDiscount(BigDecimal.TEN); + document.setDiscountPrice(BigDecimal.valueOf(90)); + document.setPublished("2020-01-01T00:00:00Z"); + document.setAverageScore(4.0f); + document.setLikeCount(BigDecimal.valueOf(100)); + document.setPublisher("Test Publisher"); + document.setCoverImageUrl("http://example.com/image.jpg"); + document.setAuthorName("Author Name"); + document.setAuthorRole("Author Role"); + + float score = 1.0f; + long searchBookCount = 1; + + // 가짜 ElasticService 생성 + ElasticService elasticService = mock(ElasticService.class); + + // When + // 가짜 ElasticService를 통해 메서드 호출 시 응답 값 설정 + when(elasticService.buildElasticSearchResultResponse(document, score, searchBookCount)) + .thenReturn(new ElasticResponse( + BigDecimal.ONE, + "Test Book", + BigDecimal.valueOf(100), + BigDecimal.TEN, + BigDecimal.valueOf(90), + Instant.parse("2020-01-01T00:00:00Z").atZone(ZoneId.systemDefault()).toLocalDate(), + 4.0f, + BigDecimal.valueOf(100), + "Test Publisher", + "http://example.com/image.jpg", + "Author Name", + "Author Role", + 1.0f, + BigDecimal.TEN, + 1 + )); + + // Then + ElasticResponse elasticResponse = elasticService.buildElasticSearchResultResponse(document, score, searchBookCount); + assertEquals("Test Book", elasticResponse.getName()); + assertEquals(BigDecimal.ONE, elasticResponse.getBookId()); + assertEquals(BigDecimal.valueOf(100), elasticResponse.getPrice()); + assertEquals(BigDecimal.TEN, elasticResponse.getDiscountRate()); + assertEquals(BigDecimal.valueOf(90), elasticResponse.getDiscountedPrice()); + assertEquals(Instant.parse("2020-01-01T00:00:00Z").atZone(ZoneId.systemDefault()).toLocalDate(), elasticResponse.getPublished()); + assertEquals(4.0f, elasticResponse.getAverageScore()); + assertEquals(BigDecimal.valueOf(100), elasticResponse.getLikeCount()); + assertEquals("Test Publisher", elasticResponse.getPublisher()); + assertEquals("http://example.com/image.jpg", elasticResponse.getCoverImageUrl()); + assertEquals("Author Name", elasticResponse.getAuthorName()); + assertEquals("Author Role", elasticResponse.getAuthorRole()); + assertEquals(1.0f, elasticResponse.getScore()); + assertEquals(BigDecimal.TEN, elasticResponse.getCategoryId()); + assertEquals(1, elasticResponse.getCount()); + } } \ No newline at end of file diff --git a/src/test/java/com/t3t/bookstoreapi/elastic/service/ElasticServiceUnitTest.java b/src/test/java/com/t3t/bookstoreapi/elastic/service/ElasticServiceUnitTest.java index e377ad2f..341cf94c 100644 --- a/src/test/java/com/t3t/bookstoreapi/elastic/service/ElasticServiceUnitTest.java +++ b/src/test/java/com/t3t/bookstoreapi/elastic/service/ElasticServiceUnitTest.java @@ -9,6 +9,7 @@ import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; import org.mockito.Mock; +import org.mockito.Mockito; import org.springframework.data.domain.PageRequest; import org.springframework.data.elasticsearch.core.SearchHit; import org.springframework.data.elasticsearch.core.SearchHits; @@ -16,10 +17,13 @@ import org.springframework.test.context.junit.jupiter.SpringExtension; import java.math.BigDecimal; +import java.time.Instant; +import java.time.ZoneId; import java.util.ArrayList; import java.util.List; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @ExtendWith(SpringExtension.class) @@ -67,4 +71,96 @@ public void testSearch() { assertEquals("Test Book", elasticResponse.getName()); assertEquals(4.0f, elasticResponse.getAverageScore()); // 검증 } + @Test + @DisplayName("엘라스틱서치 검색 기능 테스트-null인경우") + public void testSearchNull() { + String query = "test"; + String searchType = "book_name"; + PageRequest pageable = PageRequest.of(0, 10); + + ElasticService elasticService = mock(ElasticService.class); + Mockito.lenient().when(elasticService.search(query, searchType, pageable)).thenReturn(null); + + ElasticDocument document = mock(ElasticDocument.class); + Mockito.lenient().when(document.getCoverImageUrl()).thenReturn(null); + Mockito.lenient().when(document.getName()).thenReturn("Test Book"); + Mockito.lenient().when(document.getAverageScore()).thenReturn(4.0f); + + List> searchHitList = new ArrayList<>(); + searchHitList.add(new SearchHit<>(null, null, null, 1.0f, null, null, document)); + SearchHits searchHits = new SearchHitsImpl<>(1, null, 1.0f, null, searchHitList, null, null); + Mockito.lenient().when(elasticRepository.findByBookName(query, pageable)).thenReturn(searchHits); + + // When + PageResponse response = elasticService.search(query, searchType, pageable); + + // Then + if (response != null) { + ElasticResponse elasticResponse = response.getContent().get(0); + assertEquals("Test Book", elasticResponse.getName()); + assertEquals(4.0f, elasticResponse.getAverageScore()); + } + } + + @Test + @DisplayName("엘라스틱서치 검색 결과 응답 객체 생성 테스트") + public void testBuildElasticSearchResultResponse() { + // Given + ElasticDocument document = new ElasticDocument(); + document.setBookId(BigDecimal.ONE); + document.setName("Test Book"); + document.setPrice(BigDecimal.valueOf(100)); + document.setDiscount(BigDecimal.TEN); + document.setDiscountPrice(BigDecimal.valueOf(90)); + document.setPublished("2020-01-01T00:00:00Z"); + document.setAverageScore(4.0f); + document.setLikeCount(BigDecimal.valueOf(100)); + document.setPublisher("Test Publisher"); + document.setCoverImageUrl("http://example.com/image.jpg"); + document.setAuthorName("Author Name"); + document.setAuthorRole("Author Role"); + + float score = 1.0f; + long searchBookCount = 1; + + ElasticService elasticService = mock(ElasticService.class); + + // When + when(elasticService.buildElasticSearchResultResponse(document, score, searchBookCount)) + .thenReturn(new ElasticResponse( + BigDecimal.ONE, + "Test Book", + BigDecimal.valueOf(100), + BigDecimal.TEN, + BigDecimal.valueOf(90), + Instant.parse("2020-01-01T00:00:00Z").atZone(ZoneId.systemDefault()).toLocalDate(), + 4.0f, + BigDecimal.valueOf(100), + "Test Publisher", + "http://example.com/image.jpg", + "Author Name", + "Author Role", + 1.0f, + BigDecimal.TEN, + 1 + )); + + // Then + ElasticResponse elasticResponse = elasticService.buildElasticSearchResultResponse(document, score, searchBookCount); + assertEquals("Test Book", elasticResponse.getName()); + assertEquals(BigDecimal.ONE, elasticResponse.getBookId()); + assertEquals(BigDecimal.valueOf(100), elasticResponse.getPrice()); + assertEquals(BigDecimal.TEN, elasticResponse.getDiscountRate()); + assertEquals(BigDecimal.valueOf(90), elasticResponse.getDiscountedPrice()); + assertEquals(Instant.parse("2020-01-01T00:00:00Z").atZone(ZoneId.systemDefault()).toLocalDate(), elasticResponse.getPublished()); + assertEquals(4.0f, elasticResponse.getAverageScore()); + assertEquals(BigDecimal.valueOf(100), elasticResponse.getLikeCount()); + assertEquals("Test Publisher", elasticResponse.getPublisher()); + assertEquals("http://example.com/image.jpg", elasticResponse.getCoverImageUrl()); + assertEquals("Author Name", elasticResponse.getAuthorName()); + assertEquals("Author Role", elasticResponse.getAuthorRole()); + assertEquals(1.0f, elasticResponse.getScore()); + assertEquals(BigDecimal.TEN, elasticResponse.getCategoryId()); + assertEquals(1, elasticResponse.getCount()); + } } \ No newline at end of file From 7cd3fdbda56b3f773f69afef42ed635b39f5f942 Mon Sep 17 00:00:00 2001 From: PARKJONGGYEONG Date: Tue, 14 May 2024 17:29:54 +0900 Subject: [PATCH 2/2] =?UTF-8?q?test:=20testcase=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/AutocompleteController.java | 13 ++++++++++--- .../controller/AutocompleteControllerTest.java | 18 +++++++++++++++++- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/t3t/bookstoreapi/elastic/controller/AutocompleteController.java b/src/main/java/com/t3t/bookstoreapi/elastic/controller/AutocompleteController.java index 54fa9811..a725f0fd 100644 --- a/src/main/java/com/t3t/bookstoreapi/elastic/controller/AutocompleteController.java +++ b/src/main/java/com/t3t/bookstoreapi/elastic/controller/AutocompleteController.java @@ -3,6 +3,7 @@ import com.t3t.bookstoreapi.elastic.service.AutocompleteService; import com.t3t.bookstoreapi.model.response.BaseResponse; import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; @@ -23,8 +24,14 @@ public class AutocompleteController { * @author parkjonggyeong18(박종경) */ @GetMapping("/autocomplete") - public ResponseEntity>> autocomplete(@RequestParam String prefix) throws IOException { - BaseResponse> autocomplete = autocompleteService.autocomplete(prefix); - return ResponseEntity.ok().body(autocomplete); + public ResponseEntity>> autocomplete(@RequestParam String prefix) { + BaseResponse> autocomplete; + try { + autocomplete = autocompleteService.autocomplete(prefix); + return ResponseEntity.ok().body(autocomplete); + } catch (IOException e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(new BaseResponse>().message("잘못된 접근입니다.")); + } } } diff --git a/src/test/java/com/t3t/bookstoreapi/elastic/controller/AutocompleteControllerTest.java b/src/test/java/com/t3t/bookstoreapi/elastic/controller/AutocompleteControllerTest.java index c0bbd28e..1413afa8 100644 --- a/src/test/java/com/t3t/bookstoreapi/elastic/controller/AutocompleteControllerTest.java +++ b/src/test/java/com/t3t/bookstoreapi/elastic/controller/AutocompleteControllerTest.java @@ -3,6 +3,7 @@ import com.t3t.bookstoreapi.elastic.service.AutocompleteService; import com.t3t.bookstoreapi.model.response.BaseResponse; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.mockito.InjectMocks; import org.mockito.Mock; @@ -31,7 +32,8 @@ void setUp() { } @Test - void autocomplete_ReturnsExpectedResults() throws IOException { + @DisplayName("자동완성 test") + void autocompleteTest() throws IOException { // Given String prefix = "test"; List expectedData = Arrays.asList("example"); @@ -47,4 +49,18 @@ void autocomplete_ReturnsExpectedResults() throws IOException { assertEquals(HttpStatus.OK, response.getStatusCode()); assertEquals(expectedData, response.getBody().getData()); } + @Test + @DisplayName("자동완성 API 테스트 - 예외 처리") + public void testAutocompleteError() throws IOException { + // Given + String prefix = "test"; + when(autocompleteService.autocomplete(prefix)).thenThrow(IOException.class); + + // When + ResponseEntity>> responseEntity = autocompleteController.autocomplete(prefix); + + // Then + assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, responseEntity.getStatusCode()); + assertEquals("잘못된 접근입니다.", responseEntity.getBody().getMessage()); + } }