FireDrago
[Spring] DB 연결을 테스트 하기 본문
외부 DB와 연결이 필요한 리포지토리의 코드를 테스트 하려면 어떻게 해야할까?
우선 별도의 데이터베이스가 필요할 것이다. 테스트 코드가 로컬 DB 데이터를 변형 시킬 수도 있고,
테스트는 격리되어 실행되어야 한다는 테스트의 원칙을 지켜야 하기 때문이다.
그런데 별도의 DB를 만든다고 하더라도, 테스트 코드를 실행했을때, 반복해서 테스트가 성공하지 않는다.
처음에는 성공하더라도, 테스트가 실행 될때마다 데이터가 계속 쌓이면서, 두번째 테스트가 실패할 수도 있다.
그래서 트랜잭션 기능도 필요하다는 것을 알 수 있다.
스프링 부트는 별도의 DB , 트랜잭션 문제를 간단히 해결 할 수 있는 기능을 제공한다.
<임베디드 DB 설정하기>


스프링에서는 src/test/application.properties 에 test 프로필을 설정하고, DB 연결 정보를 설정한다.
그리고 Application 클래스에서 test 프로필 실행시, DataSource 빈으로 내부 h2 DB 를 생성하도록 정보를 설정한다.
이렇게 되면 테스트 코드를 실행할때, 내부 h2 DB가 생성되고, 내부 DB는 JVM 메모리 안에서 함께 생성되고, 소멸된다.
데이터 베이스를 따로 생성하여 유지할 필요가 없어지는 것이다. 오로지 테스트를 위해서 존재하는 편리한 DB이다.
스프링 부트는 여기서 더 편리하게 내부 DB를 제공한다. 위 코드의 applicaion.properties 에서 연결정보와
DataSource 빈 생성 코드를 모두 주석처리하고 테스트를 실행해보자


놀랍게도 테스트가 정상 작동한다.
스프링 부트는 DB 연결과 관련된 아무 설정도 없을때, 내부DB 를 연결하는 HirackyDataSource 를 기본으로 빈 등록한다.
즉 사용자가 연결설정을 해 줄 필요가 전혀 없다.
local 프로필을 사용할때는 외부 DB 연결을 설정하여 사용하고,
test 프로필을 사용할때는 아무런 설정없이 테스트 코드만으로 임베디드 DB를 사용하여 테스트 하자
<트랜잭션 기능>
임베디드 DB를 사용하여 테스트 격리원칙을 잘 실현했다.
이제 반복실행해도 테스트 통과하는 테스트코드를 만들기위해 트랜잭션 기능을 도입해보자

먼저 이렇게 트랜잭션 매니저를 테스트 코드에서 직접 사용하는 방법이 있을 것이다.
스프링부트는 (PlatformTransactionManager) 를 자동으로 빈 등록한다는 것을 예전에 배웠다.
그러니 TranjactionManager를 테스트 코드에서 주입받고, @BeforeEach 를 통해 매 테스트 실행 전에
transactionManager.getTransaction(new DefaultTransactionDefinition()); 으로 TransactionStatus 도 생성하고,
@AfterEach 메서드에서 transactionManager.rollback(status); 로 매번 롤백을 실행해줄 수도 있을 것이다.


그런데 스프링 부트는 이보다 훨씬 편리한 기능을 제공한다. 그냥 @Transactional 애너테이션만 붙여주면 된다.
@Transactional 애너테이션은 테스트에서 사용하면, 테스트가 끝날때 자동으로 롤백을 실행한다.
리포지토리 코드를 테스트 할때 롤백기능을 실행하기 위해 @Transactional 애너테이션만 붙여주자
※ @Transactional 을 사용할때 테스트가 실행하는 모든 리포지토리 코드는 같은 트랜잭션을 사용한다
( = 같은 커넥션을 사용한다) (트랜잭션 전파)
'프로그래밍 > Spring' 카테고리의 다른 글
| [Spring] 스프링 데이터 JPA (0) | 2024.03.11 |
|---|---|
| [Spring] MyBatis 사용하기 (0) | 2024.03.07 |
| [Spring] DB 예외처리 (0) | 2024.03.02 |
| [Spring] 트랜잭션과 스프링 (0) | 2024.02.28 |
| [Spring] 파일업로드 (0) | 2024.02.22 |
