원티드 프리온보딩 백엔드 인턴십 10월 (7기) - 첫번째 프로젝트로 소셜 미디어 통합 Feed 서비스 API를 개발하는 과제를 받았다.
나는 게시물 좋아요 API, 게시물 공유 API 구현을 담당하게 되었는데, 동작을 확인하려면 DB에 데이터를 넣어야할 것 같았다. 그런데 요구사항 명세에는 데이터 저장에 대한 부분이 없어서 저장 기능을 굳이 구현하기는 좀 (다른 테이블과 연관관계가 있어서 복잡함)... 그래서 일단 더미데이터를 넣어보기로 했다.
기능 개발을 위해 구현된 Post 엔티티는 기본 생성자 하나 뿐인데 Protect로 막혀있어서 어떤 생성자도 사용할 수 없는 상황이다. 마침 어제 공부했던 ReflectionTestUtils가 생각나서, 이걸로 테스트용 더미 데이터를 넣어보기로 했다.
ReflectionTestUtils
- 리플렉션 기반 유틸리티 메서드의 모음
- 원래라면 접근 제한되었을 변수/메서드에 접근하고 수정/호출 할 수 있게 해준다.
- ORM 프레임워크 (Jpa,Hibernate 등) Domain Entity 의 private method를 통합/단위테스트 할 때 사용할 수 있다.
package com.skeleton.feed;
import com.skeleton.feed.entity.Post;
import com.skeleton.feed.enums.SnsType;
import com.skeleton.feed.repository.PostRepository;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.RepeatedTest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.util.ReflectionTestUtils;
import java.io.BufferedReader;
import java.io.StringReader;
import java.lang.reflect.Constructor;
import java.util.Random;
import java.util.UUID;
@SpringBootTest
class DummyPostDataInit {
static SnsType[] snsTypes;
static Random random;
static BufferedReader br;
static String s = "국회나 그 위원회의\n" +
"대한민국은 국제평화의 유지에 노력하고 침략적 전쟁을 부인한다.\n" +
"중앙선거관리위원회는\n" +
"대법원장과 대법관이 아닌 법관의 임기는 10년으로 하며, 법률이 정하는 바에 의하여 연임할 수 있다.\n" +
"대통령의 국법상 행위\n" +
"국회는 국무총리 또는 국무위원의 해임을 대통령에게 건의할 수 있다.\n" +
"언론·출판은 타인의\n" +
"나는 헌법을 준수하고 국가를 보위하며 조국의 평화적 통일과 국민의 자유와 복리의 증진 및 민족문화의 창달에 노력하여 대통령으로서의 직책을 성실히 수행할 것을 국민 앞에 엄숙히 선서합니다.\n" +
"국무총리 또는 행정각\n" +
"국정감사 및 조사에 관한 절차 기타 필요한 사항은 법률로 정한다.\n" +
"형사피의자 또는 형사\n" +
"광물 기타 중요한 지하자원·수산자원·수력과 경제상 이용할 수 있는 자연력은 법률이 정하는 바에 의하여 일정한 기간 그 채취·개발 또는 이용을 특허할 수 있다.\n" +
"비상계엄이 선포된 때\n" +
"국회에 제출된 법률안 기타의 의안은 회기중에 의결되지 못한 이유로 폐기되지 아니한다. 다만, 국회의원의 임기가 만료된 때에는 그러하지 아니하다.\n" +
"언론·출판에 대한 허\n" +
"정부는 예산에 변경을 가할 필요가 있을 때에는 추가경정예산안을 편성하여 국회에 제출할 수 있다.\n" +
"대통령의 임기는 5년\n" +
"농업생산성의 제고와 농지의 합리적인 이용을 위하거나 불가피한 사정으로 발생하는 농지의 임대차와 위탁경영은 법률이 정하는 바에 의하여 인정된다.\n" +
"모든 국민은 통신의\n" +
"모든 국민은 신체의 자유를 가진다. 누구든지 법률에 의하지 아니하고는 체포·구속·압수·수색 또는 심문을 받지 아니하며, 법률과 적법한 절차에 의하지 아니하고는 처벌·보안처분 또는 강제노역을 받지 아니한다.";
@Autowired
private PostRepository postRepository;
@BeforeAll
static void init() throws Exception {
snsTypes = SnsType.values();
random = new Random();
br = new BufferedReader(new StringReader(s));
}
@RepeatedTest(10)
void addDummyData() throws Exception {
// 생성자 public으로 변경
Constructor<?>[] constructor = Post.class.getDeclaredConstructors();
constructor[0].setAccessible(true); // 접근제어자 강제 변경
Post post = (Post) constructor[0].newInstance();
//필드값 주입
ReflectionTestUtils.setField(post, "contentId", UUID.randomUUID().toString());
ReflectionTestUtils.setField(post, "title", br.readLine());
ReflectionTestUtils.setField(post, "content", br.readLine());
ReflectionTestUtils.setField(post, "type", snsTypes[random.nextInt(snsTypes.length)]); // SnsType 랜덤
//DB 저장
postRepository.save(post);
}
}
한글 Lorem Ipsum
테스트 데이터가 다 똑같거나 영어면 구분이 힘들어서 한글 Lorem Ipsum 로 더미데이터를 만들었다. 그냥 대충 해도 되긴하지만 식별이 쉬우면 아무래도 기분이 좋다.
어제 공부하면서도 쓸만하겠는데? 했던거지만 이렇게 바로 써먹게 될 줄은 몰랐는데.. 좀 더 응용하면 연관관계인 다른 엔티티에도 작업할 수 있을 것 같다. 하지만 귀찮으니 생략. 필요하면 구현해 봐야겠다.
'spring' 카테고리의 다른 글
컨트롤러 단위 테스트 방법 : @WebMvcTest (0) | 2023.10.24 |
---|---|
Spring MVC 단위 테스트 (0) | 2023.10.24 |
메소드 인자에서 @NotNull 과 @NonNull (0) | 2021.12.24 |
[Lombok] 올바른 Lombok 사용법 - @Builder (0) | 2021.12.05 |
JPA (2) 엔티티 생명주기, 영속성 컨텍스트 (0) | 2021.09.18 |