다양한 필터링의 조회 검색 기능을 만들게 되었다.
그리고 테스트하기 위해서는 많은 insert문을 실행하는 setup 메소드를 만들게 되었는데 문제가 생겼다.
실제 dataSetup코드..
public void dataSetup() {
Member aMember = memberRepository.save(Member.builder().email("www.a.com").nickname("aaaa name").profileImage("image").build());
Member bMember = memberRepository.save(Member.builder().email("www.b.com").nickname("bbbb name").profileImage("image").build());
Member cMember = memberRepository.save(Member.builder().email("www.c.com").nickname("cccc name").profileImage("image").build());
TechStack react = techStackRepository.save(TechStack.builder().name("react").build());
TechStack angular = techStackRepository.save(TechStack.builder().name("angular").build());
TechStack spring = techStackRepository.save(TechStack.builder().name("spring").build());
TechStack nodejs = techStackRepository.save(TechStack.builder().name("nodejs").build());
TechStack php = techStackRepository.save(TechStack.builder().name("php").build());
Project aProject = projectRepository.save(Project.builder().member(aMember)
.title("aaaa title").content("aaaa content").status(ProjectStatus.RECRUITING).build());
Project bProject = projectRepository.save(Project.builder().member(bMember)
.title("bbbb title").content("bbbb content").status(ProjectStatus.RECRUITING).build());
Project cProject = projectRepository.save(Project.builder().member(cMember)
.title("cccc title").content("cccc content").status(ProjectStatus.COMPLETED).build());
Project dProject = projectRepository.save(Project.builder().member(aMember)
.title("dddd title").content("dddd content").status(ProjectStatus.COMPLETED).build());
projectTechStackRepository.save(new ProjectTechStack(aProject, react))
.setProject(aProject);
projectTechStackRepository.save(new ProjectTechStack(aProject, spring))
.setProject(aProject);
projectTechStackRepository.save(new ProjectTechStack(aProject, nodejs))
.setProject(aProject);
projectTechStackRepository.save(new ProjectTechStack(bProject, react))
.setProject(bProject);
projectTechStackRepository.save(new ProjectTechStack(bProject, spring))
.setProject(bProject);
projectTechStackRepository.save(new ProjectTechStack(bProject, nodejs))
.setProject(bProject);
projectTechStackRepository.save(new ProjectTechStack(cProject, php))
.setProject(cProject);
projectTechStackRepository.save(new ProjectTechStack(cProject, react))
.setProject(cProject);
projectTechStackRepository.save(new ProjectTechStack(dProject, php))
.setProject(dProject);
projectTechStackRepository.save(new ProjectTechStack(dProject, angular))
.setProject(dProject);
projectRepository.save(aProject);
projectRepository.save(bProject);
projectRepository.save(cProject);
projectRepository.save(dProject);
System.out.println("-------------------- insert query close ----------------\n\n");
}
- 시간이 상당히 걸린다..
어차피 전부 조회로직이라 사전에 삽입된 데이터의 변경로직이 없어
BeforeEach등을 사용하여 매번 테스트 함수마다 setup을 실행시키려면 매번 데이터도 지워줘야하고
무엇보다 시간이 너무 걸리고 굳이 그럴필요 있나라고 생각이 들었다.
@BeforeAll
- junit5에서 제공해주는 어노테이션
테스트클래스가 시작할 때 한번만 동작하는 어노테이션을 찾았지만 이것은 함수가 static이여야만 동작한다.
그러면 setup함수에서 호출하는 repository도 전부 static에 테스트메소드들도 전부 static이 되어야해서 문제가 됐다.
@TestInstance
- TestInstance.Lifecycle 설정이 가능. (default :PER_METHOD)
- JUnit 5는 테스트 인스턴스 생성 기본 단위가 메소드라서
테스트 클래스 속 각 테스트메소드 별로 따로 인스턴스가 생성되어 테스트가 실행 된다. - 테스트메소드 간 영향없이 독립적인 단위 테스트를 하기에 좋은데, 그럴필요가 없을 땐 사용자 임의로 변경해 줄수가 있었다.
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@DataJpaTest
@ExtendWith(SpringExtension.class)
class QueryRepositoryTest {
@Autowired
private QueryRepository queryRepository;
@BeforeAll
public void dataSetup() {
queryRepository.save(..);
queryRepository.save(..);
queryRepository.save(..);
//...
}
@Test
void 조회테스트1() {}
@Test
void 조회테스트2() {}
@Test
void 조회테스트3() {}
}
이런식으로 @TestInstance(TestInstance.Lifecycle.PER_CLASS)을 붙이면
testInstance lifecycle을 클래스 단위로 변경되고 @BeforeAll이 붙은 메소드가 static이 아니어도 경고가 안뜨고 올바르게 동작한다.
결과
처음에 setup시에만 시간이 많이 걸리고 나머지는 시간이 대폭 줄었다!
테스트코드 초록표시는 언제봐도 짜릿하구나
reference : https://www.baeldung.com/java-beforeall-afterall-non-static
'spring' 카테고리의 다른 글
(Spring) Stomp로 채팅 동시접속자 구현해보기 (2) | 2022.09.10 |
---|
댓글