본문 바로가기

Spring

[Spring] @SpringBootTest vs @DataJpaTest

테스트 코드를 작성하고 새로 작성된 테스트 코드를 돌려볼 때 실행 시간이 너무 오래 걸렸다.

이를 기존에 @SpringBootTest로 작성된 코드를 @DataJpaTest 변경하면서 해결할 수 있었는 데 변경하는 중에 공부한 것들을 정리해 보았다.

@SpringBootTest

  • @SpringBootTest가 붙은 테스트코드가 실행되면 @ComponentScan 내의 모든 Bean 객체가 ApplicationContext에 올라간후 실행된다. 
  • 실제 서버 실행 환경과 비슷한 환경에서 진행되는 테스트인만큼 통합테스트에 유리하다.

@DataJpaTest

  • ApplicationContext에 JPA에 필요한 것들만 등록한다. (Entity, JpaRepository)
  • InMemoryDB(H2 database)를 사용한다.

적용

testImplementation 'com.h2database:h2'

우선 test에 사용될 H2 의존성을 추가해준다.

 

그후 @SpringBootTest 를 @DataJpaTest로 변경해준다.

 

NoSuchBeanDefinitionException: No qualifying bean of type 'com.querydsl.jpa.impl.JPAQueryFactory'

만약 QueryDsl을 사용중이라면 위와 같은 에러가 뜰 수 있는데 

스프링 공식문서를 보면 위에서 말한 것 처럼 JPA관련한 것들만 등록하기 때문에 QueryDsl Configuration은 등록되지 않은 상태이다. 

(https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#features.testing.spring-boot-applications.autoconfigured-spring-data-jpa)

 

이를 해결하기 위해서는 수동으로 빈을 현재 ApplicationContext에 올려줘야 하는데

@DataJpaTest
@ImportAutoConfiguration(QuerydslConfig.class)
class ConferenceRepositoryTest {

@Import@ImportAutoConfiguration 으로 등록할 수 있다. 

@Import는 명시적 Configuration을 수동으로 가져오는 것이고 @ImportAutoConfiguration은 Auto Configuration Class를 등록하는 것이다. 실제로 QuerydslConfig는 임의로 내가 만든 클래스인데 왜 ImportAutoConfiguration에 작동하는지는 모르겠다. 현재까지 사용해본 결과 저 두 어노테이션을 교차사용해도 문제가 없었는데 이에 대해서는 조금 더 공부해봐야 할 것 같다.

 

 

Service나 Controller는 Mock객체를 만들어서 테스트를 진행했기 때문에 실제 위의 설정이 사용된 곳은 Repository 테스트뿐이지만 이렇게 변경하면서 테스트 시간을 많이 줄일 수 있었다. 

'Spring' 카테고리의 다른 글

[Spring] RabbitMQ를 이용한 이벤트 예약  (0) 2023.08.09
[Spring] 패키지 구조(계층형, 도메인형)  (0) 2023.01.14