관리 메뉴

JIE0025

[Testcode][슬라이스][Service] CategoryServiceTest 본문

백엔드/테스트

[Testcode][슬라이스][Service] CategoryServiceTest

Kangjieun11 2023. 1. 9. 02:27
728x90

 

 

 


 

컨트롤러 슬라이스 테스트와 마찬가지로 슬라이스 테스트이므로 서비스 로직이 잘 돌아가는지만 확인하면 되어서 4가지 테스트만 만들어주었다.

 

package com.FlagHome.backend.domain.category.service;

import com.FlagHome.backend.domain.category.entity.Category;
import com.FlagHome.backend.domain.category.repository.CategoryRepository;

import com.FlagHome.backend.global.util.CustomBeanUtils;
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.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;

import static org.assertj.core.api.Assertions.assertThat;

import java.util.List;
import java.util.Optional;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;

import static org.mockito.ArgumentMatchers.any;

import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.when;

//@SpringBootTest 대신 @InjectMocks, @Mock, @ExtendWith을 사용해서 IOC Container가 생성 x >> 스프링에 의존 x
// 서비스만 객체로 생성되어 매우 빠른 테스트 제공 가능
@ExtendWith(MockitoExtension.class)    //가짜객체 Mockito 사용을 알리기 위함.
public class CategoryServiceTest {

    @InjectMocks
    private CategoryService categoryService; //Mock객체가 주입될 클래스
    @Mock
    private CategoryRepository categoryRepository; //서비스에선 레포지토리가 필수이므로 가짜객체 Mock 생성

    @Mock
    private CustomBeanUtils beanUtil;


    @Test
    @DisplayName("[서비스] 카테고리 추가 테스트")
    public void createCategoryTest() {
        //given
        Category category = Category.builder()
                .koreanName("알고리즘")
                .englishName("algorithm")
                .categoryDepth(0L)
                .build();

        //mocking
        given(categoryRepository.save(any())).willReturn(category);

        //when
        Category createdCategory = categoryService.createCategory(category);

        //then  //hamcrest
        assertThat(createdCategory.getCategoryDepth(),is(category.getCategoryDepth()));
        assertThat(createdCategory.getKoreanName(),is(category.getKoreanName()));
        assertThat(createdCategory.getEnglishName(),is(category.getEnglishName()));

    }

    @Test
    @DisplayName("[서비스] 카테고리 수정 테스트")
    public void updateCategoryTest() {
        //given

        //원본카테고리 데이터가 아래라고 가정
        Category originalCategory = Category.builder()
                .koreanName("알고리즘")
                .englishName("algorithm")
                .categoryDepth(1L)
                .build();
        originalCategory.setId(0L);

        //수정데이터
        Category category = Category.builder()
                .koreanName("알고리즘-코테반")
                .englishName("algorithm-codetest")
                .build();
        category.setId(0L);

        //결과
        Category result = Category.builder()
                .koreanName("알고리즘-코테반")
                .englishName("algorithm-codetest")
                .categoryDepth(1L)
                .build();
        result.setId(0L);

        //mocking
        given(categoryRepository.findById(Mockito.any(Long.class))).willReturn(Optional.ofNullable(originalCategory));
        given(categoryRepository.save(Mockito.any(Category.class))).willReturn(result);
        given(beanUtil.copyNotNullProperties(Mockito.any(Category.class),Mockito.any(Category.class))).willReturn(result);

        //when
        Category updatedCategory = categoryService.updateCategory(category);

        //then //assertJ
        assertThat(updatedCategory.getId()).isEqualTo(result.getId());
        assertThat(updatedCategory.getCategoryDepth()).isEqualTo(result.getCategoryDepth());
        assertThat(updatedCategory.getKoreanName()).isEqualTo(result.getKoreanName());
        assertThat(updatedCategory.getEnglishName()).isEqualTo(result.getEnglishName());
    }

    @Test
    @DisplayName("[서비스] 전체 카테고리 읽기 테스트")
    public void getCategoriesTest() {
        //given
        //부모 자식 카테고리 관계 세팅
        Category depth0Activity = Category.builder()
                .categoryDepth(0L).koreanName("활동").englishName("activity").build();

        Category depth0Notice = Category.builder()
                .categoryDepth(0L).koreanName("공지").englishName("notice").build();

        Category depth1Study = Category.builder()
                .categoryDepth(1L).koreanName("스터디").englishName("study")
                .parent(depth0Notice)
                .build();

        Category depth2Algorithm = Category.builder()
                .categoryDepth(2L).koreanName("알고리즘-코테반").englishName("algorithm-codetest")
                .parent(depth1Study)
                .build();


        List<Category> categories = List.of(
                depth0Activity, depth0Notice
        );

        //mocking
//        given(categoryRepository.findAll(Mockito.any())).willReturn(categories);
        when(categoryRepository.findAll()).thenReturn(categories);

        //when
        List<Category> resultList = categoryService.getCategories();

        //then 단정문
        assert resultList.size() == 2; //depth가 0인 애들을 가져오기 떄문에 전체 데이터의 개수만 세어준다. (통합테스트에선 자식도 확인할 수 있을 것)
    }


    @Test
    @DisplayName("[서비스] 카테고리 삭제 테스트")
    public void deleteCategory() {
        //given
        long categoryId = 1L;
        Category deleteCategory = Category.builder().build();
        deleteCategory.setId(categoryId);

        Mockito.when(categoryRepository.findById(categoryId)).thenReturn(Optional.ofNullable(deleteCategory)).thenReturn(null);

        //when  //then
        categoryService.deleteCategory(categoryId);

    }


}