단위 테스트를위한 ReflectionTestUtils

2021. 3. 23. 15:55·Tech/Spring

Mockito를 이용한 테스트 코드 작성시 발생한 이슈를 간단히 정리하고자 합니다.

 

@Table(name = "category")
@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Category extends BaseEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "name")
    private String name;

    @Column(name = "parent_id")
    private Long parentId;

    @Builder
    public Category(String name, Long parentId) {
        this.name = name;
        this.parentId = parentId;
    }

}
  • 제가 보통 쓰는 엔티티 코드방식입니다.
  • 클래스 상단에 @Builder를 선언하면 IDENTITY전략을 설정한 기본키 값에 값을 할당할 수 있기에, 안전하지 않습니다.
  • 따라서, 생성자에 @Builder를 선언하여 엔티티 생성시 필요한 데이터만 받을 수 있도록 작성하였습니다.
  • 추가적으로 엔티티에는 @Setter 메소드를 선언하면 좋지 않습니다. 엔티티 혹은 객체는 불변한 성질을 가져야 하기 때문입니다. 만약 중간에 변경될 요지를 준다면 추후 코드추적하기가 어렵습니다.

 

@ExtendWith(MockitoExtension.class)
class CategoryServiceTest {

    @Mock
    private CategoryRepository categoryRepository;

    @Test
    @DisplayName("카테고리 조회")
    void categoryOneDepthSelect() {

        given(categoryRepository.findAll()).willReturn(getStubCatogories());
        CategoryService categoryService = new CategoryService(categoryRepository);

        CategoryDto categoryRoot = categoryService.categoryRoot();

        System.out.println(categoryRoot);

        assertThat(categoryRoot.getSubCategories().size()).isEqualTo(2);
        assertThat(categoryRoot.getSubCategories().get(0).getSubCategories().size()).isEqualTo(2);
        assertThat(categoryRoot.getSubCategories().get(1).getSubCategories().size()).isEqualTo(2);
    }

}
  • 목데이터로 테스트를 하기 위해 Mockito를 사용하였습니다.
  • 단위 테스트에 대한 자세한 내용은 아래 게시글을 참조 바랍니다

brunch.co.kr/@springboot/536

 

[임시 글..나중에 지울 예정] 단위 테스트 예습

스터디 중에.. 테스트 코드 작성이 너무 어렵다는 분들이 계셔서, 단위 테스트에 대해서 간략하게 먼저 소개합니다. 이 글은, 제가 이전에 작성했던 아래 글의 내용의 일부를 인용하였습니다. htt

brunch.co.kr

 

    private List<Category> getStubCatogories() {
        Category sub1 = new Category("SUB1", 0L);
        Category sub2 = new Category("SUB2", 0L);
        Category sub11 = new Category("SUB1-1", 1L);
        Category sub12 = new Category("SUB1-2", 1L);
        Category sub21 = new Category("SUB2-1", 2L);
        Category sub22 = new Category("SUB2-2", 2L);

        ReflectionTestUtils.setField(sub1, "id", 1L);
        ReflectionTestUtils.setField(sub2, "id", 2L);
        ReflectionTestUtils.setField(sub11, "id", 3L);
        ReflectionTestUtils.setField(sub12, "id", 4L);
        ReflectionTestUtils.setField(sub21, "id", 5L);
        ReflectionTestUtils.setField(sub22, "id", 6L);

        List<Category> categories = List.of(
            sub1, sub2, sub11, sub12, sub21, sub22
        );
        return categories;
    }
  • 카테고리 리스트에 대한 더미 데이터를 만들어야 했습니다.
  • 통합 테스트를 한다면, CategoryRepository의 findAll 메소드를 통해 DB에 존재하는 카테고리 데이터를 읽어와 사용할 수 있습니다.
  • 하지만, 단위테스트를 사용해야했기에 Category 엔티티를 직접 만들어야 했습니다.
  • Category 엔티티에서 Id 필드는 private 타입, setter 메소드 존재 X, 생성자 필드 X 하기 때문에 id 필드를 주입해야 했습니다.
  • ReflectionTestUtils를 이용하여 private 필드값에 직접 할당 할 수 있습니다.
    • spring-context 5.1.2 / spring-test 5.1.2 모듈이 필요합니다. 최신 스프링부트 버전을 사용하신다면 바로 사용하실 수 있습니다.

 

    @Test
    public void testRead1(){
        List<Category> stubCatogories = getStubCatogories();
        stubCatogories.forEach(category -> {
            System.out.println(category.getId());
        });
    }

  • 만든 더미데이터를 출력해보면 정상적으로 직접 세팅한 id값을 확인할 수 있습니다.

 

참고

www.baeldung.com/spring-reflection-test-utils

 

 

저작자표시 (새창열림)

'Tech > Spring' 카테고리의 다른 글

Mybatis와 Jpa 사용시 트랜잭션 묶어서 사용하는 방법(※ 멀티 datasource 설정 / QueryDsl)  (1) 2021.07.24
Spring Filter에서 request Body 가공하기  (1) 2021.07.19
Springboot + GCP Cloud Storage 연동(파일 업로드, 다운로드)  (1) 2021.03.22
Spring Boot에서 Actuator 및 Spring Actuator Admin 설정 방법  (0) 2021.03.21
Google 소셜 로그인 Google API 클라이언트 라이브러리 + GoogleIdTokenVerifier 사용하는 방법  (5) 2021.03.15
'Tech/Spring' 카테고리의 다른 글
  • Mybatis와 Jpa 사용시 트랜잭션 묶어서 사용하는 방법(※ 멀티 datasource 설정 / QueryDsl)
  • Spring Filter에서 request Body 가공하기
  • Springboot + GCP Cloud Storage 연동(파일 업로드, 다운로드)
  • Spring Boot에서 Actuator 및 Spring Actuator Admin 설정 방법
소프
소프
  • 소프
    기회는 찬스
    소프
  • 전체
    오늘
    어제
    • 분류 전체보기 (138)
      • Language (20)
        • Java (19)
        • Design Pattern (1)
      • Tech (27)
        • Spring (19)
        • JPA (3)
        • QueryDSL (1)
        • Gradle (4)
      • 개발 생각 (1)
      • IT Book (0)
        • 자바_스프링 개발자를 위한 실용주의 프로그래밍 (0)
      • Database (4)
        • Mysql (4)
        • Redis (0)
      • 네트워크 (1)
      • 운영체제 (2)
      • IDE (12)
        • Intellij (9)
        • vscode (2)
        • datagrip (1)
      • 인프라 (11)
        • Docker (2)
        • Jenkins (7)
        • Github Actions (1)
        • GCP (1)
      • 형상관리 (2)
        • gitlab (2)
        • git (0)
      • 외부활동 (44)
        • CS 면접 끝장내기 - 데이터베이스 1기 (5)
        • CS 면접 끝장내기 - 컴퓨터 네트워크 2기 (5)
        • CS 면접 끝장내기 - 자바 2기 (0)
        • TDD, 클린 코드 with Java 17기 (7)
        • ATDD, 클린 코드 with Spring 8기 (6)
        • 루퍼스 2기 (21)
      • 프로젝트 (0)
      • 회고 (6)
      • 기타 (1)
        • 제미니의 개발 실무 (0)
  • 블로그 메뉴

    • 홈
    • Github
    • LinkedIn
    • 방명록
  • 인기 글

  • 최근 댓글

  • hELLO· Designed By정상우.v4.10.6
소프
단위 테스트를위한 ReflectionTestUtils
상단으로

티스토리툴바