인프런 커뮤니티 질문&답변

jimmy0613님의 프로필 이미지
jimmy0613

작성한 질문수

스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술

테스트 코드 작성에 대한 질문

해결된 질문

작성

·

255

·

수정됨

0

테스트 코드를 작성할 때 테스트하려는 메서드를 제외한 나머지 메서드들은 전부 정상적으로 동작한다고 가정하고 해야하는 건가요??

테스트코드를 작성하다보니 헷갈려서 질문 드립니다..

 

예를 들면 findById() 메서드를 테스트할때

save() 메서드는 정상 동작한다고 가정하고 하는건가요?

답변 2

0

안녕하세요. jimmy0613님, 공식 서포터즈 코즈위버 입니다.

테스트 코드 작성 범위에 대한 질문이네요.

프로젝트를 시작하면 우선 엔터티부터 작성하게 되는데요, 엔터티 설계가 제대로 되었음을 확인하기 위해 save, findById 같은 기본적인 테스트를 작성합니다. 질문하신 것중 init() 메서드는 이 때 작성하게 됩니다. Service 는 아직 나오지 않았기에 Repository 테스트 단계가 되겠네요.

이후 서비스가 나오고 나면 이제 서비스 테스트 코드를 작성하는 단계에 들어갑니다. 서비스 테스트 단계에서는 엔터티가 무결하다고 전제하고(Repository 테스트를 이미 완료했으므로) 서비스 자체 기능에만 집중해서 테스트를 합니다. 서비스에 요청을 하고 기대한 결과가 나오는지에만 집중하는 테스트를 하는 것이지요. 엔터티 무결 같은 내용은 고려하지 않습니다. 이처럼 테스트도 단계에 따라 목적이 달라집니다.

그리고, 샘플 데이터의 경우 저는 테스트 코드가 실행되기 전에 사전에 샘플 데이터를 밀어넣는 코드를 함께 실행하도록 하는 편입니다.

감사합니다.

jimmy0613님의 프로필 이미지
jimmy0613
질문자

아, 서비스 테스트를 하기 전에 먼저 레파지토리 테스트를 거치지 않아서 혼란스러웠던거네요. 감사합니다

0

jimmy0613님의 프로필 이미지
jimmy0613
질문자

#레파지토리
package groupware.board.repository;

import groupware.board.domain.Category;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Repository
public class CategoryRepository {

    private static final Map<Long, Category> store = new HashMap<>();
    private static Long sequence = 0L;

    public Map<Long, Category> getStore() {
        return store;
    }

    public Long getSequence() {
        return ++sequence;
    }

    public void save(Category category) {
        store.put(category.getId(), category);
    }
    /**
     * sample data
     */
    @PostConstruct
    public void init() {
        save(new Category(++sequence, "SampleCategory1"));
        save(new Category(++sequence, "SampleCategory2"));
    }

    /**
     * for test
     */
    public void clear() {
        store.clear();
    }

}
#서비스
package groupware.board.service;

import groupware.board.domain.Category;
import groupware.board.repository.CategoryRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
@RequiredArgsConstructor
public class CategoryServiceImpl implements CategoryService {

    private final CategoryRepository categoryRepository;

    public Category save(Category category) {
        category.setId(categoryRepository.getSequence());
        categoryRepository.save(category);
        return category;
    }

    public List<Category> findAll() {
        return new ArrayList<>(categoryRepository.getStore().values());
    }

    public Category findById(Long id) {
        List<Category> categories = findAll();
        for (Category category : categories) {
            if (category.getId().equals(id)) {
                return category;
            }
        }
        return null;
    }

    /**
     * for test
     */
    public void clearStore() {
        categoryRepository.clear();
    }

}
#테스트
package groupware.board.service;

import groupware.board.domain.Category;
import org.junit.jupiter.api.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;

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

@SpringBootTest
class CategoryServiceImplTest {

    @Autowired
    CategoryService categoryService;

    @Test
    void init() {
        //given

        //when
        List<Category> categories = categoryService.findAll();

        //then
        assertThat(categories.size()).isEqualTo(2);
        assertThat(categories.get(0).getCategoryName()).isEqualTo("SampleCategory1");
        assertThat(categories.get(1).getCategoryName()).isEqualTo("SampleCategory2");
    }

    @Test
    void findById() {
        //given

        //when
        Category findCategory1 = categoryService.findById(1L);
        Category findCategory2 = categoryService.findById(2L);

        //then
        assertThat(findCategory1.getCategoryName()).isEqualTo("SampleCategory1");
        assertThat(findCategory2.getCategoryName()).isEqualTo("SampleCategory2");

    }

    @Test
    void save() {
        //given
        Category newCategory = categoryService.save(new Category("newCategory"));

        //when
        Category savedCategory = categoryService.findById(newCategory.getId());

        //then
        assertThat(savedCategory).isEqualTo(newCategory);
    }

}

강의를 듣고 복습하는 겸 DB 연결 하기 전에 강사님이 하신 것처럼 map으로 저장소를 만들고, 대신 저는 서비스까지 추가해서 해봤는데..

레파지토리에 있던 메서드들을 서비스로 옮기려니 중복이 생기고 좀 애매해진 것 같아서 코드에 대한 피드백도 해주시면 감사하겠습니다..

테스트는 전체, 각각 돌려도 모두 성공이긴 한데..

스스로 제대로 작성한 것인지 확신이 안듭니다 ㅠ

질문을 명확하게 드리자면,

  1. init() 메서드를 테스트 할 필요성이 있는지

  2. findById() 메서드를 테스트할 때, 저는 초기 데이터를 기준으로 테스트하였는데 새로운 카테고리를 추가한 다음 테스트해야하는지

  3. 2번의 대답이 yes 라면 findById() 테스트는 save()가 정상 동작한다는 가정 하에 이루어지는 건지

궁금합니다..

테스트 코드는 독립적으로 작성해야 한다고 배웠는데 제가 이해가 부족한지 강사님이 하실 땐 이해가 잘 되는 것 같았는데 갑자기 너무 헷갈립니다

jimmy0613님의 프로필 이미지
jimmy0613
질문자

CategoryRepositoryTest와 CategoryServiceTest를 분리했더니 좀 명확해진 것 같습니다..

이것도 틀릴 수 있지만 ㅠ

package groupware.board.repository;

import groupware.board.domain.Category;
import groupware.board.service.CategoryService;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.*;

@SpringBootTest
class CategoryMemoryRepositoryTest {

    @Autowired
    CategoryMemoryRepository categoryMemoryRepository;

    @Autowired
    CategoryService categoryService;

    @Test
    void init() {
        //given
        categoryMemoryRepository.clear();

        //when
        categoryMemoryRepository.init();
        List<Category> categories = categoryService.findAll();

        //then
        assertThat(categories.size()).isEqualTo(2);
        assertThat(categories.get(0).getCategoryName()).isEqualTo("SampleCategory1");
        assertThat(categories.get(1).getCategoryName()).isEqualTo("SampleCategory2");
    }


}
package groupware.board.service;

import groupware.board.domain.Category;
import groupware.board.repository.CategoryRepository;
import org.junit.jupiter.api.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;

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

@SpringBootTest
class CategoryServiceImplTest {

    @Autowired
    CategoryService categoryService;

    @BeforeEach
    void beforeEach() {
        categoryService.clear();
    }


    @Test
    void findById() {
        //given
        Category newCategory = categoryService.addCategory(new Category("newCategory"));

        //when
        Category findCategory = categoryService.findById(newCategory.getId());

        //then
        assertThat(newCategory).isEqualTo(findCategory);
    }

    @Test
    void add() {
        //given
        Category newCategory = categoryService.addCategory(new Category("newCategory"));

        //when
        List<Category> categories = categoryService.findAll();

        //then
        assertThat(categories).contains(newCategory);
    }

    @Test
    void update() {
        //given
        Category savedCategory = categoryService.addCategory(new Category("beforeUpdate"));
        String updateName = "AfterUpdate";

        //when
        categoryService.updateCategory(savedCategory, updateName);

        //then
        assertThat(savedCategory.getCategoryName()).isEqualTo(updateName);
    }

    @Test
    void delete() {
        //given
        Category deleteCategory = categoryService.addCategory(new Category("deleteCategory"));

        //when
        categoryService.deleteCategory(deleteCategory.getId());

        //then
        assertThat(categoryService.findAll()).doesNotContain(deleteCategory);
    }
}
jimmy0613님의 프로필 이미지
jimmy0613

작성한 질문수

질문하기