Search
Duplicate

Spring에서 profile을 이용하여 TEST용 DB분리

분야
BE
주제
테스트
Spring
DB
심각도
낮음🤒
제보자
담당자
작성자
상태
처리 완료
이슈링크(optional)
작성일자
2023/04/07 13:09
공개여부
공개
글감

문제 상황

1.
h2라는 데이터베이스에서는 인메모리로 데이터베이스를 만들어 주는 기능을 제공한다.
2.
인메모리 데이터베이스는 local에 데이터베이스를 따로 세팅하지 않아도 JVM에서 간편하게 데이터베이스를 사용할 수 있다. 따라서 테스트용 데이터베이스 구축을 쉽게 만들 수 있다.
3.
서비스용 데이터베이스와 테스트용 데이터베이스(인메모리 디비)를 나누어 설정하는 간편한 방법을 찾고싶다.

결과

이 글을 통해 만드는 환경은 다음과 같다.
1.
서비스하는 데이터베이스용 application-local.yml을 만든다. (여기서는 mariadb를 이용 할 것이다.)
2.
테스트를 하기위한 인메모리 데이터베이스용 application-test.yml 을 만든다. (H2를 이용 할 것이다.)
3.
서비스용 데이터베이스와 테스트용 데이터베이스가 잘 작동하는지 확인한다.

gradle

plugins { id 'java' id 'org.springframework.boot' version '2.7.9' id 'io.spring.dependency-management' version '1.0.15.RELEASE' } group 'org.example' version '1.0-SNAPSHOT' repositories { mavenCentral() } dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' // 1 runtimeOnly 'org.mariadb.jdbc:mariadb-java-client' // 2 // test testImplementation 'org.junit.jupiter:junit-jupiter-api' testRuntimeOnly 'org.junit.jupiter:junit-jupiter' testImplementation 'org.springframework.boot:spring-boot-starter-test' // 3 testRuntimeOnly 'com.h2database:h2' // 4 } test { useJUnitPlatform() }
Groovy
복사
1) spring jpa를 사용하기 위해서 추가했다.
2) 서비스에서 mariadb를 사용하기 위해 추가했다.
3) spring을 test코드에 잘 적용하기 위해 추가했다.
4) test에서는 h2를 사용하기 위해 추가했다.

서비스용 데이터베이스 만들기

# application-local.yml # application-{profile_name}.yml 을 이름으로 결정한다. spring: config: activate: on-profile: local # profile이름은 local로 설정 datasource: driver-class-name: org.mariadb.jdbc.Driver url: jdbc:mariadb://localhost:3306/test_db?serverTimezone=Asia/Seoul username: testuser password: userpassword jpa: hibernate: ddl-auto: create # 1 database-platform: org.hibernate.dialect.MariaDB103Dialect
YAML
복사
1) ddl 생성에 대한 설정을 한다.
create: 매번 데이터베이스를 생성하고 끝날 때 삭제하지 않는다.
create-drop: 데이터베이스를 생성하고 끝날 때 삭제한다.
update: 엔티티 구조에 따라 데이터베이스를 변경한다.
none: 아무런 동작도 하지 않는다.
validate: 데이터베이스 스키마를 검증한다.

테스트용 데이터베이스 만들기

# application-test.yml spring: config: activate: on-profile: test datasource: url: jdbc:h2:mem:testdb username: sa password: password driver-class-name: org.h2.Driver jpa: hibernate: ddl-auto: create-drop database-platform: org.hibernate.dialect.H2Dialect
YAML
복사

데이터베이스 확인

# docker-compose.yml version: "3.8" services: mariadb: image: mariadb:latest environment: MARIADB_ROOT_PASSWORD: rootpassword MARIADB_DATABASE: test_db MARIADB_USER: testuser MARIADB_PASSWORD: userpassword ports: - "3306:3306
YAML
복사
서비스용 db를 생성하는 docker compose file

Test용 코드

application.yml

# application.yml spring: profiles: default: local jpa: properties: hibernate: show_sql: true # 1 format_sql: true # 2 globally_quoted_identifiers: true # 3
YAML
복사
1) 모든 sql을 콘솔의 기록합니다.
2) sql을 예쁘게 기록한다.
3) sql문에서 식별자를 keyword도 사용할 수 있습니다. (sql문에서 식별자를 큰따옴표로 묶습니다.)

java 예제코드

// main/java/org/example/Main package org.example; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Main { public static void main(String[] args) { SpringApplication.run(Main.class, args); } }
Java
복사
// main/java/org/example/User package org.example; import javax.persistence.*; @Entity @Table(name = "USER") public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "USER_ID") private Long id; @Column(name = "ROW") private String row; @Column(name = "COLUMN") private String column; public Long getId() { return id; } public String getColumn() { return column; } public String getRow() { return row; } public User(String row, String column) { this.row = row; this.column = column; } public User() { } }
Java
복사
// main/java/org/example/UserRepository package org.example; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @Repository public interface UserRepository extends JpaRepository<User, Long> { }
Java
복사
Main을 실행하면 mariadb로 잘 연결되었다는 것을 확인할 수 있다.

java test코드

아래는 Test환경에서 h2데이터베이스를 사용하는 코드이다.
// test/java/org/example/UserRepositoryTest package org.example; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.ActiveProfiles; import static org.junit.jupiter.api.Assertions.*; @SpringBootTest @ActiveProfiles("test") public class UserRepositoryTest { @Autowired private UserRepository userRepository; @Test public void testConnection() { assertTrue(userRepository.findAll().isEmpty()); User user = new User("row", "column"); user = userRepository.save(user); User cmp = userRepository.findById(user.getId()).orElseThrow(); assertEquals(user.getId(), cmp.getId()); assertEquals(user.getRow(), cmp.getRow()); assertEquals(user.getColumn(), cmp.getColumn()); } }
Java
복사
위 테스트 코드를 실행하면 h2를 이용한 코드가 생성되는 것을 볼 수 있다.
@ActiveProfiles 어노테이션을 통해 여러가지 profile을 골라서 추가할 수 있다.

gradle을 사용하고 @ActiveProfiles를 사용하지 않는 방법

만약 test코드에서 @ActiveProfiles 를 계속 붙이는 것이 번거롭다면 gradle 설정을 바꾸어 해결할 수도 있다.
test { useJUnitPlatform() systemProperty 'spring.profiles.active', 'test' }
Groovy
복사
test 부분을 위와같이 고치면 자동으로 test환경에서 profile이 test가 된다.

참고자료

하이버네이트 유저가이드(설정)

application properties

gradle을 이용하여 profiles설정하기