쿼리 dsl 테스트 코드작성
@DataJpaTest
리포지토리를 테스트 할 때, @SpringBootTest 어노테이션을 이용할 수도 있지만 ,
@DataJpaTest 어노테이션을 이용하면 더 빠르게 테스트 결과를 확인 할 수 있습니다.
( @SpringBootTest 어노테이션을 이용할 경우 모든 configuration, context, components를 로드합니다. )
@DataJpaTest는 오직 JPA 컴포넌트들만을 테스트하기 위한 어노테이션으로써, 아래와 같이 db연결, jpa 테스트와 연관된 config만 적용되는 것을 확인할 수 있습니다.
또한 @Transactional 어노테이션을 보유하고 있어서 테스트 후 자동으로 롤백됩니다.
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
※ 기본적으로 인메모리 데이터베이스를 사용할 수도 있지만, 기존 설정한 db를 사용하려고 한다면 위 코드를 추가해주면 됩니다.
- JpaQueryFactory
@DataJpaTest에서 QueryDsl을 이용하기 위해서 jpaQueryFactory를 이용하려면 다음과 같은에러가 발생합니다.
org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.querydsl.jpa.impl.JPAQueryFactory'
쿼리 dsl 테스트 코드를 작성할 경우, @DataJpaTest를 사용할 수 없을까요?
@DataJpaTest를 이용하는 경우에도 EntityManager의 경우 주입을 받을 수 있기 때문에
@DataJpaTest
class InsuranceHistoryRepositorySupportTest {
@Autowired
EntityManager em;
private JPAQueryFactory queryFactory;
@BeforeEach
void init(){
queryFactory = new JPAQueryFactory(em);
}
@Test
@DisplayName("어제자 보험가입 요청 조회 성공")
void findRequestsByInsuranceStepYesterday() {
//given
Rider rider = Rider.builder()
.name("이재형")
.driverId("dd1234")
.build();
em.persist(rider);
InsuranceHistory history = InsuranceHistory.builder()
.insuranceStep(2)
.rider(rider)
.historyType(HistoryType.REQUEST)
.createDate(LocalDateTime.now().minusDays(1))
.build();
em.persist(history);
InsuranceHistory history2 = InsuranceHistory.builder()
.insuranceStep(2)
.rider(rider)
.historyType(HistoryType.REQUEST)
.createDate(LocalDateTime.now().minusDays(2))
.build();
em.persist(history2);
LocalDateTime startDate = LocalDateTime.of(LocalDate.now().minusDays(1), LocalTime.MIN);
LocalDateTime endDate = LocalDateTime.of(LocalDate.now().minusDays(1),LocalTime.MAX);
//when
List<InsuranceHistory> result = queryFactory.selectFrom(insuranceHistory)
.where(insuranceHistory.insuranceStep.eq(2),
insuranceHistory.createDate.between(startDate, endDate))
.fetch();
//then
assertThat(result.size()).isEqualTo(1);
assertThat(result.get(0).getRider()).isEqualTo(rider);
}
}
위와 같은 방식으로 @BeforeEach어노테이션을 이용하여 JpaQueryFactory를 이용한 테스트 코드를 작성할 수 있게 됩니다.
위 코드로 테스트를 진행하면 다음과 같이 성공 결과를 확인할 수 있습니다.
- @SpringBootTest를 이용하는 경우
@Transactional
@SpringBootTest
class InsuranceHistoryRepositorySpringBootTest {
@Autowired InsuranceHistoryRepositorySupport insuranceHistoryRepositorySupport;
@Autowired EntityManager em;
@Test
void findRequestsByInsuranceStepYesterday(){
//given
Rider rider = Rider.builder()
.name("이재형")
.driverId("dd1234")
.build();
em.persist(rider);
InsuranceHistory history = InsuranceHistory.builder()
.insuranceStep(2)
.rider(rider)
.historyType(HistoryType.REQUEST)
.build();
em.persist(history);
InsuranceHistory history2 = InsuranceHistory.builder()
.insuranceStep(2)
.rider(rider)
.historyType(HistoryType.REQUEST)
.build();
em.persist(history2);
//when
List<InsuranceHistory> result = insuranceHistoryRepositorySupport.findRequestsByInsuranceStepToday(2);
//then
assertThat(result.size()).isEqualTo(2);
assertThat(result.get(0).getRider()).isEqualTo(rider);
}
}
동일한 테스트를 @SpringBootTest를 이용하여 진행할 경우, 테스트는 성공하지만 @DataJpaTest를 이용했을 때보다 응답 속도가 느리다는 것을 확인할 수 있습니다.
https://www.inflearn.com/questions/23063
@DataJpaTest - 인프런 | 질문 & 답변
QueryDsl 강의 잘듣고 있습니다! QueryDsl을 사용하면 @DataJpaTest를 사용하지 못하나요? JPAQueryFactory에 대해서 NoSuchBeanDefinitionException이 발생하는데 따로 주입하는 방법을 모르겠습니다ㅠㅠ - 질문 & 답
www.inflearn.com