해결된 질문
작성
·
260
·
수정됨
답변 2
0
안녕하세요. jimmy0613님, 공식 서포터즈 코즈위버 입니다.
테스트 코드 작성 범위에 대한 질문이네요.
프로젝트를 시작하면 우선 엔터티부터 작성하게 되는데요, 엔터티 설계가 제대로 되었음을 확인하기 위해 save, findById 같은 기본적인 테스트를 작성합니다. 질문하신 것중 init() 메서드는 이 때 작성하게 됩니다. Service 는 아직 나오지 않았기에 Repository 테스트 단계가 되겠네요.
이후 서비스가 나오고 나면 이제 서비스 테스트 코드를 작성하는 단계에 들어갑니다. 서비스 테스트 단계에서는 엔터티가 무결하다고 전제하고(Repository 테스트를 이미 완료했으므로) 서비스 자체 기능에만 집중해서 테스트를 합니다. 서비스에 요청을 하고 기대한 결과가 나오는지에만 집중하는 테스트를 하는 것이지요. 엔터티 무결 같은 내용은 고려하지 않습니다. 이처럼 테스트도 단계에 따라 목적이 달라집니다.
그리고, 샘플 데이터의 경우 저는 테스트 코드가 실행되기 전에 사전에 샘플 데이터를 밀어넣는 코드를 함께 실행하도록 하는 편입니다.
감사합니다.
0
#레파지토리
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으로 저장소를 만들고, 대신 저는 서비스까지 추가해서 해봤는데..
레파지토리에 있던 메서드들을 서비스로 옮기려니 중복이 생기고 좀 애매해진 것 같아서 코드에 대한 피드백도 해주시면 감사하겠습니다..
테스트는 전체, 각각 돌려도 모두 성공이긴 한데..
스스로 제대로 작성한 것인지 확신이 안듭니다 ㅠ
질문을 명확하게 드리자면,
init() 메서드를 테스트 할 필요성이 있는지
findById() 메서드를 테스트할 때, 저는 초기 데이터를 기준으로 테스트하였는데 새로운 카테고리를 추가한 다음 테스트해야하는지
2번의 대답이 yes 라면 findById() 테스트는 save()가 정상 동작한다는 가정 하에 이루어지는 건지
궁금합니다..
테스트 코드는 독립적으로 작성해야 한다고 배웠는데 제가 이해가 부족한지 강사님이 하실 땐 이해가 잘 되는 것 같았는데 갑자기 너무 헷갈립니다
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);
}
}
아, 서비스 테스트를 하기 전에 먼저 레파지토리 테스트를 거치지 않아서 혼란스러웠던거네요. 감사합니다