본문 바로가기

Spring Boot/스프링 부트 핵심 가이드

[SpringBoot] H2를 테스트용 DB로 사용하기

📌 테스트용 DB로서의 H2


DB관련 테스트에는 인메모리 방식의 DB인 H2가 많이 사용됨
1. 테스트 과정에서 데이터가 영향을 받을수 있으며
2. H2를 이용하면 더 빨리 테스트할 수 있기 때문

임베디드 H2를 사용하려면 의존성을 추가해줘야 함

# gradle
dependencies {
    testRuntimeOnly 'com.h2database:h2'
}

 

🤔 테스트 데이터를 롤백하면 굳이 H2를 쓸 이유가 없지 않나?
테스트 데이터가 롤백되어 DB에 남아있지 않더라도,
auto increment로 지정한 ID가 증가되는 등의 문제가 발생할 수 있음
=> 테스트용 DB 필요
참고 : https://jungguji.github.io/2020/07/05/H2-DB%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%9C-Repository-Test/

📌 @DataJpaTest 어노테이션


  • JPA와 관련된 설정(Entity, Repository)만 로드해서 테스트를 진행
    → 필요한 객체를 @Autowired로 주입받을 수 있음
  • 이때 스프링 컨테이너를 이용하지 않으므로 @SpringTest보다 빠른 테스트를 할 수 있음
  • @Transactional 어노테이션이 포함되어 있어서 
    테스트 코드가 종료되면 자동으로 데이터베이스의 롤백이 진행됨 (= 테스트 이전 상태로 복귀)
  • @ExtendWith(SpringExtension.class) 어노테이션이 포함되어 있음, 따로 작성하지 않아도 됨
  • 테스트시 참조할 DB로 임베디드 H2를 사용함 
    따라서 @DataJpaTest 를 사용할 때 H2 디펜던시가 없으면 오류 발생
  • 임베디드 H2가 아닌 DB를 참조하고 싶을 때는
    @AutoConfigureTestDatabas(replace = Replace.NONE) 어노테이션을 추가로 붙이면 됨
    이 어노테이션은 자동으로 DB를 구성할 것인지에 대한 설정을 해줌

📌 테스트용 H2 설정 방법


지금까지의 설정만으로도 H2를 사용하여 테스트를 할 수 있지만,
하지만 추가적인 설정이 적용된 H2를 사용하고 싶으면 appliation-test.yml을 수정하면 됨

spring:

  datasource:
    username: sa
    password:
    driver-class-name: org.h2.Driver
    url: jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;MODE=MySQL

  h2:
    console:
      enabled: true

  jpa:
    database: h2
    properties:
      hibernate:
        dialect: org.hibernate.dialect.MySQLDialect
        ddl-auto: create-drop
    show-sql: true
    generate-ddl: true
    database-platform: org.hibernate.dialect.H2Dialect

 

이후 이 설정이 반영된 H2를 사용하도록 테스트 클래스에
@ActiveProfiles("test")
@AutoConfigureTestDatabase(replace = Replace.NONE)
@TestPropertySource(locations = "classpath:application-test.yml")
어노테이션을 반드시 붙여줘야 함

c.f. AutoConfigureTestDatabase 어노테이션을 붙이지 않으면 발생할 수 있는 에러 : 
https://0soo.tistory.com/41

출처:  https://0soo.tistory.com/41

📌 정리) H2를 테스트용 DB로 사용하는 방법


  1. H2 디펜던시 추가
  2. 테스트 클래스에 @DataJpaTest 어노테이션 사용
  3. application-test.yml 설정
  4. 테스트 클래스에
    @ActiveProfiles("test")
    @AutoConfigureTestDatabase(replace = Replace.NONE)
    @TestPropertySource(locations = "classpath:application-test.yml") 사용

 

+ 원래는 레포지토리 테스트에 대한 글을 쓰려 했는데,
findById나 save 같은 기본 메소드는 검증을 마치고 제공되므로 테스트가 의미 없다고 함.
JPQL 이나 네이티브 쿼리에 대해서만 검사를 실행하면 된다고 해서
JPQL을 사용할 때 정리하면 될 듯!