포스트

Spring Boot - Testcontainers로 MariaDB 테스트하기

Spring Boot로 사이드 프로젝트를 시작하면서 docker를 사용하여 mariadb 환경을 설정했다.
테스트에서도 유사한 환경을 구사하기 위해 Testcontainers 라이브러리를 사용할 수 있었고 그 과정을 기록!! ✍️


실행 환경

  • Spring Boot 3.3.4
  • Testcontainers 1.20.3


Testcontainers 간략히 알아보기

Testcontainers는 Docker 컨테이너를 활용해 테스트를 수행할 수 있도록 돕는 Java 라이브러리로, 통합 테스트에서 자주 사용된다. 이 라이브러리를 통해 테스트는 독립적이고 일관된 환경에서 실행되며, 실제 운영 환경과 유사한 MariaDB를 사용해 테스트할 수 있다. 특히, 컨테이너 환경에서 테스트가 진행되므로 외부 환경에 영향을 받지 않는다는 장점이 있다.

-> Testcontainers Link 🔗


DataJpaTest 진행해보기

1. Spring Boot 프로젝트에 라이브러리 추가

build.gradle

1
2
3
4
5
dependencies {
  testImplementation "org.testcontainers:testcontainers:1.20.3"  
  testImplementation "org.testcontainers:junit-jupiter:1.20.3"  
  testImplementation "org.testcontainers:mariadb:1.20.3"
}


2. MariadbTestContainer 객체 생성

profile을 하나만 사용(default profile)하는 경우테스트를 위한 test profile을 사용하는 경우에 대해 정리


방법 1. 테스트용 profile이 없는 경우 - test db 계정 정보를 동적으로 설정

MariadbContainer 객체를 생성한 후 @DynamicPropertySource를 이용해서 동적으로 application.yml의 db 설정을 변경한다.

MariadbTestContainer.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import org.springframework.test.annotation.DirtiesContext;  
import org.springframework.test.context.DynamicPropertyRegistry;  
import org.springframework.test.context.DynamicPropertySource;  
import org.testcontainers.containers.MariaDBContainer;  
import org.testcontainers.junit.jupiter.Container;  
import org.testcontainers.junit.jupiter.Testcontainers;

@Testcontainers  
@DirtiesContext
class MariadbTestContainer {  
  
    @Container  
    public static final MariaDBContainer mariadb = new MariaDBContainer<>("mariadb:latest")  
            .withDatabaseName("testdb")  
            .withUsername("tester")  
            .withPassword("1234");  
  
    @DynamicPropertySource  
    static void setDatasourceProperties(DynamicPropertyRegistry registry) {  
        registry.add("spring.datasource.url", mariadb::getJdbcUrl);  
        registry.add("spring.datasource.username", mariadb::getUsername);  
        registry.add("spring.datasource.password", mariadb::getPassword);  
    }    
  
}
  • @Testcontainers: Testcontainers 적용
  • @Container: docker 컨테이너 인스턴스를 생성하고 생명주기를 관리
  • @DynamicPropertySource: application.yml의 데이터베이스 설정을 테스트 컨테이너의 MariaDB 설정으로 대체하기 위해 사용
  • @DirtiesContext: 하위 클래스가 동적 프로퍼티를 가진 자체적인 ApplicationContext를 얻을 수 있게 해줌


방법 2. test profile 사용

TestContainer 설정을 test profile(application-test.yml)에 작성한 후 MariadbTestContainer를 실행한다.

MariadbTestContainer.java

1
2
3
4
5
6
7
8
9
10
11
12
13
import org.springframework.test.context.ActiveProfiles;  
import org.testcontainers.containers.MariaDBContainer;  
import org.testcontainers.junit.jupiter.Container;  
import org.testcontainers.junit.jupiter.Testcontainers;

@ActiveProfiles("test")
@Testcontainers  
class MariadbTestContainer {  
  
    @Container  
    public static final MariaDBContainer mariadb = new MariaDBContainer<>("mariadb:latest");  
  
}
  • @Testcontainers: Testcontainers 적용
  • @Container: docker 컨테이너 인스턴스를 생성하고 생명주기를 관리

application-test.yml

1
2
3
4
5
6
spring:  
  datasource:  
    url: jdbc:tc:mariadb://testdb  
    username: tester  
    password: 1234


3. DataJpaTest 작성

SiteRepositoryTest.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import org.junit.jupiter.api.Test;  
import org.springframework.beans.factory.annotation.Autowired;  
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;  
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;  
  
@DataJpaTest  
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
class SiteRepositoryTest extends MariadbTestContainer {  
  
    @Autowired private SiteRepository siteRepository;  
  

    @Test  
    void test() {  
        List<SiteEntity> siteEntityAll = siteRepository.findAll();  

        assertThat(siteEntityAll.size()).isZero();  
    }  
  
}
  • @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
    DataJpaTest에서 H2 등 임베디드 DB를 사용하지 않고 application.yml 설정 적용





참고한 사이트

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.