Blog

[Spring][HCD 추가 2일차]71 검색부분 테스트코드 작성해보기

Category
Author
Tags
PinOnMain
1 more property
테스트코드 부족한 부분 생각
검색 기능 테스트 코드 구현 중
@ExtendWith(MockitoExtension.class)를 사용하는 경우와
MockitoAnnotations.initMocks(this)를 + @BeforeEach 메서드를 사용하는 경우
간단하게 검색의 성공과 실패에 대한 테스트 코드를 작성해보았다.
class SearchServiceTest { @Mock private MenuRepository menuRepository; @Mock private StoreRepository storeRepository; @InjectMocks private SearchService searchService; @BeforeEach void setUp() { MockitoAnnotations.initMocks(this); } @Test @DisplayName("메뉴와 가게 이름으로 검색 성공") public void testSearchStoresAndMenusByKeyword_Success() { // given String keyword = "1"; List<Menu> mockMenus = new ArrayList<>(); List<Store> mockStores = new ArrayList<>(); // 가짜 메뉴와 가게 데이터를 생성하고 Mock 설정 Menu menu1 = new Menu(); menu1.setMenuName("Menu 1"); Store store1 = new Store(); store1.setId(1L); store1.setStoreName("Store 1"); menu1.setStore(store1); mockMenus.add(menu1); Menu menu2 = new Menu(); menu2.setMenuName("Menu 2"); Store store2 = new Store(); store2.setId(2L); store2.setStoreName("Store 2"); menu2.setStore(store2); mockMenus.add(menu2); when(menuRepository.findByMenuNameContaining(keyword)).thenReturn(mockMenus); when(storeRepository.findByStoreNameContaining(keyword)).thenReturn(mockStores); // when List<SearchResponseDto> responseDtos = searchService.searchStoresAndMenusByKeyword(keyword); // then assertEquals(mockMenus.size() + mockStores.size(), responseDtos.size()); // 메뉴 검색 결과 확인 for (Menu menu : mockMenus) { assertTrue(responseDtos.stream().anyMatch(dto -> dto.getType().equals("menu") && dto.getStoreName().equals(menu.getStore().getStoreName()))); } // 가게 검색 결과 확인 for (Store store : mockStores) { assertTrue(responseDtos.stream().anyMatch(dto -> dto.getType().equals("store") && dto.getStoreName().equals(store.getStoreName()))); } } }
Java
복사
이 코드에서의 문제점은 Entity에 직접 Setter 메소드가 필요한 점이었다. 이는 테스트 코드를 위해서 실제 프로젝트의 Entity 클래스에 @Setter가 필요해지면서 데이터를 변형 시킬 수 있는 가능성이 높아져서 테스트코드의 의도와는 다르게 의도하지 않은 DB 조작이 발생할 수 있어 올바르지 않다.
따라서 Mockito 모의 객체를 생성하는 방식으로 변경해보았다.
class SearchServiceTest { @Mock private MenuRepository menuRepository; @Mock private StoreRepository storeRepository; @InjectMocks private SearchService searchService; @BeforeEach void setUp() { MockitoAnnotations.initMocks(this); } @Test @DisplayName("메뉴와 가게 이름으로 검색 성공") public void testSearchStoresAndMenusByKeyword_Success() { // given String keyword = "1"; List<Menu> mockMenus = new ArrayList<>(); List<Store> mockStores = new ArrayList<>(); // Mock 객체 생성 및 설정 Menu menu1 = mock(Menu.class); when(menu1.getMenuName()).thenReturn("Menu 1"); Store store1 = mock(Store.class); when(store1.getId()).thenReturn(1L); when(store1.getStoreName()).thenReturn("Store 1"); when(menu1.getStore()).thenReturn(store1); mockMenus.add(menu1); Menu menu2 = mock(Menu.class); when(menu2.getMenuName()).thenReturn("Menu 2"); Store store2 = mock(Store.class); when(store2.getId()).thenReturn(2L); when(store2.getStoreName()).thenReturn("Store 2"); when(menu2.getStore()).thenReturn(store2); mockMenus.add(menu2); when(menuRepository.findByMenuNameContaining(keyword)).thenReturn(mockMenus); when(storeRepository.findByStoreNameContaining(keyword)).thenReturn(mockStores); // when List<SearchResponseDto> responseDtos = searchService.searchStoresAndMenusByKeyword(keyword); // then assertEquals(mockMenus.size() + mockStores.size(), responseDtos.size()); // 메뉴 검색 결과 확인 for (Menu menu : mockMenus) { assertTrue(responseDtos.stream().anyMatch(dto -> dto.getType().equals("menu") && dto.getStoreName().equals(menu.getStore().getStoreName()))); } // 가게 검색 결과 확인 for (Store store : mockStores) { assertTrue(responseDtos.stream().anyMatch(dto -> dto.getType().equals("store") && dto.getStoreName().equals(store.getStoreName()))); } } @Test @DisplayName("메뉴와 가게 이름으로 검색 실패 - 데이터 없음") public void testSearchStoresAndMenusByKeyword_Failure_NoData() { // given String keyword = "nonexistent"; List<Menu> mockMenus = new ArrayList<>(); List<Store> mockStores = new ArrayList<>(); when(menuRepository.findByMenuNameContaining(keyword)).thenReturn(mockMenus); when(storeRepository.findByStoreNameContaining(keyword)).thenReturn(mockStores); // when List<SearchResponseDto> responseDtos = searchService.searchStoresAndMenusByKeyword(keyword); // then assertEquals(0, responseDtos.size()); } }
Java
복사
Mock객체를 통해서 모의 Menu, Store를 생성할 수 있으며, 객체의 필드 또한 모의 필드값을 입력하면서 마치 DB에 있는 데이터처럼 테스트를 진행 할 수 있다.
기본적인 성공 실패 보다 많은 예외 및 유효성검사 와 관련된 테스트 케이스를 만들어볼 필요가 있다.