[SpringBoot] H2 테스트용 데이터베이스 초기화

dondonee·2024년 4월 4일
0
post-thumbnail
post-custom-banner

테스트에서는 데이터베이스를 휘발성으로 사용하는 것이 편리하다. H2 인메모리 데이터베이스를 사용하거나 @Transactional 애노테이션을 사용하는 방법이 있다.

그러나 이 경우 매번 데이터베이스의 스키마나 초기 데이터를 만들어줘야 하는 번거로움이 있는데, 외부 SQL 파일을 통해 테스트가 시작될 때마다 간편하게 데이터베이스를 초기화할 수 있다.



방법1) H2 데이터베이스의 경우

JDBC URL 설정

spring:
  datasource:
    url: jdbc:h2:<url>;INIT=RUNSCRIPT FROM '~/create.sql'
    username: sa

애플리케이션 설정(application.yml)에서 JDBC URL에 스키마 파일의 경로를 추가해준다. (INIT=runscript from '~/init.sql';)

인메모리 모드(jdbc:h2:mem:)와 서버 모드(jdbc:h2:tcp://) 모두 가능하다.


여러 개의 초기화 파일을 사용하는 경우

String url = "jdbc:h2:mem:test;INIT=runscript from '~/create.sql'\\;runscript from '~/init.sql'";

자바 또는 properties 파일에서는 세미콜론 이스케이프를 위해 백 슬래시를 두 번 입력해준다(\\;).

<property name="url" value=
"jdbc:h2:mem:test;INIT=create schema if not exists test\;runscript from '~/sql/init.sql'"
/>

XML 파일에서는 한 번만 입력하면 된다(\;).



방법2) @Sql 애노테이션 사용

url: jdbc:h2:tcp://localhost/~/testonly;INIT=runscript from '~/init.sql';MODE=MySQL;DATABASE_TO_LOWER=TRUE;CASE_INSENSITIVE_IDENTIFIERS=TRUE;IGNORECASE=TRUE

홈 디렉토리(~)에 SQL 파일을 두고 테스트해보았더니 초기화가 잘 되었다.

그런데 버전 관리를 하기 위해서 SQL 파일을 클래스패스(/rc/test/resources)로 옮겨오고 URL을 변경한 경로에 맞게 (classpath:init.sql)로 변경했는데 ApplicationContext를 로드할 수 없다는 오류가 발생했다.


인텔리제이 Project Structure를 확인해봤는데 Test Resources 디렉토리가 클래스패스로 정상적으로 등록되어있는 상태였다.

아무래도 JDBC URL로는 클래스패스가 인식되지 않는 것 같아 다른 방법을 찾았다.


테스트 클래스에 @Sql 설정

@Slf4j
@Transactional
@SpringBootTest
@Sql(scripts = "classpath:/init.sql")
public class MyBatisPostRepositoryTest {}

테스트 클래스에 위와 같이 @Sql 애노테이션을 사용하면 된다.

참고로 스프링의 @Transactional은 테스트에서 사용하는 경우 데이터 뿐 아니라 스키마도 테스트 이전 상태로 되돌려준다. 일반적인 트랜잭션 개념에서 DDL은 바로 커밋되므로 롤백이 안 되지만, @Transactional이 적용된 스프링 테스트에서 @Sql의 초기화 파일을 사용해 등록한 스키마는 테스트가 종료된 후 삭제된다.




🔗 References

연관 포스팅

post-custom-banner

0개의 댓글