데이터 접근 기술 - 테스트
spring.profiles.active=test
spring.datasource.url=jdbc:h2:tcp://localhost/~/test
spring.datasource.username=sa
logging.level.org.springframework.jdbc=debug
데이터 접근 기술에 대해 더 알아보기 전에 데이터베이스에 연동하는 테스트에 대해서 알아보자
데이터 접근 기술은 실제 데이터베이스에 접근해서 데이터를 잘 저장하고 조회할 수 있는지 확인하는 것이 필요하다.
test에 있는 application.properties 파일에도
spring.profiles.active=test
spring.datasource.url=jdbc:h2:tcp://localhost/~/test
spring.datasource.username=sa
logging.level.org.springframework.jdbc=debug
생성, 수정의 경우에는 상관없지만
조회의 경우에는 로컬에서 사용하는 데이터베이스를 같이 공유하고 쓰고있어서 문제가 생긴다.
이럴 때 해결방법은 간단하게 H2 데이터베이스를 용도에 따라 2가지로 구분하면 된다.
데이터베이스를 생성하면 해결
데이터베이스를 생성하고 spring.datasource.url 부분을 작성한대로 수정해서 사용하면 된다.
하지만 또 테스트를 실행하다보면 문제가 발생한다.
여기서 발생하는 문제는 테스트는 여러번 반복할 수 있어야한다는 점이다.
테스트의 원칙
- 테스트는 다른 테스트와 격리해야 한다.
- 테스트는 반복해서 실행할 수 있어야 한다.
물론 테스트 끝날 때 마다 DELETE SQL을 사용할 수 있겠지만 완전한 해결방법은 아니다.
이때 도움이 되는게 트랜잭션이다
테스트가 끝난이후에 트랜잭션을 롤백하면 데이터가 깔끔하게 제거된다.
테스트를 하면서 데이터를 이미 저장한 상황에도, 테스트가 실패해 롤백을 호출하지 못한다고 해도
트랜잭션이 커밋을 하지않았기 때문에 데이터베이스에 반영되지않아서 괜찮다.
이때 테스트 실행 전후로 동작하는 @BeforeEach, @AfterEach라는 편리한 기능을 사용해서 트랜잭션을 사용할 수 있다.
하지만 가장 간편한 방법은 @Transactionl 어노테이션을 도입하면 된다.
@Transactional 원리
스프링이 제공하는 @Transactional 애노테이션은 로직이 성공적으로 수행되면 커밋하도록 동작한다.
그런데 @Transactional 애노테이션을 테스트에서 사용하면 아주 특별하게 동작한다.
@Transactional이 테스트에 있으면 스프링은 테스트를 트랜잭션 안에서 실행하고, 테스트가 끝나면 트랜잭션을 자동으로 롤백시켜 버린다!
테스트 - 임베디드 모드 DB
테스트 케이스를 실행하기 위해서는 별도의 데이터베이스를 설치하고, 운영하는 것은 상당히 번잡한 작업이다.
단순히 테스트를 검증할 용도로만 사용하기 때문에 테스트가 끝내면 데이터베이스의 데이터를 모두 삭제해도 된다.
더 나아가서 테스트가 끝나면 데이터베이스 자체를 제거해도 된다.
임베디드 모드
H2 데이터베이스는 자바로 개발되어 있고, JVM안에서 메모리 모드로 동작하는 특별한 기능을 제공한다.
그래서 애플리케이션을 실행할 때 H2 데이터베이스도 해당 JVM 메모리에 포함해서 함께 실행할 수 있다.
DB를 애플리케이션에 내장해서 함께 실행한다고 해서 임베디드 모드(Embedded mode)라 한다.
물론 애플리케이션이 종료되면 임베디드 모드로 동작하는 H2 데이터베이스도 함께 종료되고, 데이터도 모두 사라진다.
쉽게 말해서 애플리케이션에서 자바 메모리를 함께 사용하는 라이브러리처럼 동작하는 것이다.
스프링부트는 별다른 설정이 없으면 임베디드 데이터베이스를 사용하게 설정되어있어서 편리하다.