스프링 DB - 테스트

Heeeoh·2024년 3월 12일
0

스프링 DB

목록 보기
9/9
post-thumbnail

🌿 시작하기 앞서


스프링 부트 2.6.5 버전을 기준으로 작성됨
H2 데이터베이스 Version 2.2.224 (2023-09-17)
강의에서 제공하는 기본 소스코드에서 DB 관련 기술만 학습

application.propertiessrc/mainsrc/test는 다른 구역이므로 테스트에서도 동일한 환경을 사용한다면 src/testapplication.properties도 설정해주자.

spring.profiles.active=test
spring.datasource.url=jdbc:h2:tcp://localhost/~/test
spring.datasource.username=sa

logging.level.org.springframework.jdbc=debug

dataSource가 이 정보를 토대서 생성됨


🌱 테스트


✔️ 로컬 DB 테스트

@SpringBootTest 애노테이션은 @SpringBootApplication을 찾아서 설정으로 사용한다.

H2 데이터베이스로 테스트를 실패할 경우 2가지를 확인하자
1. H2 데이터베이스 실행 여부
2. H2 데이터베이스의 데이터 초기화 여부

로컬에서 사용하는 애플리케이션 서버와 테스트에서 같은 데이터베이스를 사용해서 문제가 발생한다.

가장 간단한 방법
테스트 전용 데이터베이스를 별도로 운영

  • jdbc:h2:tcp://localhost/~/test local에서 접근하는 서버 전용 데이터베이스
  • jdbc:h2:tcp://localhost/~/testcase test 케이스에서 사용하는 전용 데이터베이스

생성방법은
서버 재실행 -> url에 testcase등으로 바꾸고 연결 하면 testcase.mv.db가 생성된다.
이제 jdbc:h2:tcp://localhost/~/testcase 이 url로 접속

src/test appliation.properties도 변경

spring.profiles.active=test
spring.datasource.url=jdbc:h2:tcp://localhost/~/testcase
spring.datasource.username=sa

테스트의 중요한 원칙

  • 테스트는 다른 테스트와 격리해야 한다.
  • 테스트는 반복해서 실행할 수 있어야 한다.

테스트가 끝날때마다 delete sql을 사용하는 것은 테스트 도중 예외 발생시 애플리케이션이 종료되버리면 delete sql을 실행할 수 없기 때문에 좋지 않다.


✔️ 데이터 롤백


트랜잭션을 사용하면 해결된다.

1. 트랜잭션 시작
2. 테스트 A 실행
3. 트랜잭션 롤백

4. 트랜잭션 시작
5. 테스트 B 실행
6. 트랜잭션 롤백

.
.
.

테스트는 각각의 테스트 실행 전 후로 동작하는 @BeforeEach , @AfterEach 라는 편리한 기능을 제공

//트랜잭션 관련 코드
@Autowired
PlatformTransactionManager transactionManager; //스프링 부트 자동 빈 등록 
TransactionStatus status;

@BeforeEach
void beforeEach() {
	//트랜잭션 시작
	status = transactionManager.getTransaction(new DefaultTransactionDefinition());
}

@AfterEach
void afterEach() {
	//MemoryItemRepository 의 경우 제한적으로 사용
	if (itemRepository instanceof MemoryItemRepository) {
		((MemoryItemRepository) itemRepository).clearStore();
	}

	//트랜잭션 롤백
 	transactionManager.rollback(status);
 }

✔️ @Transactional


사실 더 좋은 방법이 있는데 @Transactional 애노테이션 하나만 붙이면 된다. 이러면 각 테스트 전 후로 트랜잭션 시작, 롤백을 자동으로 해준다. 해당 기능은 test에서만 적용된다.

메서드나 클래스에 @Transactional 이 있으면 트랜잭션을 시작한다.
테스트 메서드가 끝나면 트랜잭션을 강제로 롤백한다.

참고
트랜잭션을 테스트에서 시작하기 때문에 서비스, 리포지토리에 있는 @Transactional 도 테스트에서
시작한 트랜잭션에 참여한다. 라고 하는데 트랜잭션 전파라는 것을 배워야 하나보다. 같은 트랜잭션 범위에 들어간다 라고 알아두자


강제 커밋 @Commit

@Commit 애노테이션을 클래스 또는 메서드에 붙이면 테스트 종료 후 롤백 대신 커밋이 호출된다.
@Rollback(value = false) 도 마찬가지이다.


✔️ 임베디드 모드 DB


테스트 케이스 실행을 위해 별도의 데이터베이스 설치, 설정, 운영은 번잡한 작업이다.

H2 데이터베이스는 자바로 개발되었고, JVM 안에서 메모리 모드로 동작하는 특별한 기능을 제공한다.
즉, JVM 메모리에 H2 데이터베이스를 포함해서 함께 실행이 가능하다. 이를 임베디드 모드 라 한다.
(DB를 애플리케이션에 내장)

애플리케이션이 종료되면 임베디드 모드로 동작하는 H2 데이터베이스도 함께 종료, 데이터도 모두 삭제

// h2 임베디드 메모리 DB 사용
@Bean
@Profile("test")
public DataSource dataSource() {
	log.info("메모리 데이터베이스 초기화");
	DriverManagerDataSource dataSource = new DriverManagerDataSource();
	dataSource.setDriverClassName("org.h2.Driver");
	dataSource.setUrl("jdbc:h2:mem:db;DB_CLOSE_DELAY=-1"); // 임베디드 메모리 모드
	dataSource.setUsername("sa");
	dataSource.setPassword("");
	return dataSource;
}
  • @Profile("test")
    • 프로필이 test인 경우에만 데이터소스를 스프링 빈으로 등록
    • 테스트 케이스에서만 이 데이터소스를 스프링 빈으로 등록해서 사용하겠다는 뜻
  • dataSource()
    • jdbc:h2:mem:db : 중요! 데이터소스를 만들때 이렇게만 적으면 임베디드 모드(메모리 모
      드)로 동작하는 H2 데이터베이스를 사용 가능
    • DB_CLOSE_DELAY=-1 : 임베디드 모드에서는 데이터베이스 커넥션 연결이 모두 끊어지면 데이터베이스도 종료되는 것을 방지하는 설정

✔️ 스프링 부트와 임베디드 모드


스프링 부트는 임베디드 데이터베이스에 대한 설정도 기본으로 제공한다.
데이터베이스에 대한 별다른 설정이 없으면 임베디드 데이터베이스를 사용

데이터베이스에 접근하는 DataSource 설정 정보도 주석처리

application.properties의 datasource 설정 정보도 주석처리

이로써 스프링부트가 임베디드 데이터베이스를 제공한다.

 conn0: url=jdbc:h2:mem:0e4053f9-xxxx-xxxx-xxxx-xxxxxxxxxxx user=SA] 

테스트를 실행하면 이런 식으로 임베디드 모드가 연결된 것을 확인 할 수 있다.


✔️ 스프링 부트 - 기본 SQL 스크립트를 사용한 데이터베이스 초기화 기능


메모리 DB는 애플리케이션 종료될 때 함께 사라지기에 실행 시점에 데이터베이스 테이블도 새로 만들어 줘야한다.

스프링 부트는 SQL 스크립트를 실행해서 애플리케이션 로딩 시점에 데이터베이스를 초기화하는 기능 제공

src/test/resource/schema.sql 해당 위치에 schema.sql 파일을 생성

drop table if exists item CASCADE;
create table item
(
	id bigint generated by default as identity,
	item_name varchar(10),
	price integer,
	quantity integer,
	primary key (id)
);

sql문을 입력해놓으면 된다.


🔖 학습내용 출처

스프링 DB 2편 - 데이터 접근 활용 기술

profile
열심히 살자

0개의 댓글