Spring Boot Testcontainers 환경 구축하기

NCOOKIE·2025년 4월 21일
0

TIL

목록 보기
18/20

개요

테스트 코드 작성 시 동일한 개발 환경을 구축하기 위해서 Testcontainers 환경을 구축해봤다.

테스트 컨테이너는 JUnit을 지원하는 Java 라이브러리로, 도커 컨테이너 기반의 일회용 인스턴스를 제공한다. 각종 DBMS의 이미지를 이용해 내가 아는 DB 그대로 사용할 수 있고, 통합 테스트, UI 테스트 등 각종 테스트에 활용 가능하다.

스프링에서 기본적으로 지원해주는 H2 데이터베이스는 별도의 설정이 필요없고 인메모리 기반이라 빠르지만, 운영 환경의 데이터베이스와 일부 다르게 동작할 수 있다. Testcontainers는 실제 운영 환경과 유사한 데이터베이스 환경에서 테스트할 수 있어서 잠재적인 문제를 사전에 발견할 수 있다.

설정

여기서는 MySQL을 기준으로 설정했다. 다른 DB를 사용한다면 공식 문서를 참고하자.

당연히 Docker는 기본적으로 설치되어 있어야 한다.

build.gradle

// test container
testImplementation 'org.springframework.boot:spring-boot-testcontainers'
testImplementation 'org.testcontainers:junit-jupiter'
testImplementation 'org.testcontainers:mysql:1.20.6'          // MySQL 컨테이너 사용

AbstractIntegrationTest.java

@Testcontainers
public abstract class AbstractIntegrationTest {

    @Container
    protected static final MySQLContainer<?> MYSQL_CONTAINER = new MySQLContainer<>("mysql:8.0")
            .withDatabaseName("test-db")
            .withUsername("test")
            .withPassword("test");

    @DynamicPropertySource
    static void overrideProps(DynamicPropertyRegistry registry) {
        registry.add("spring.datasource.url", MYSQL_CONTAINER::getJdbcUrl);
        registry.add("spring.datasource.username", MYSQL_CONTAINER::getUsername);
        registry.add("spring.datasource.password", MYSQL_CONTAINER::getPassword);
        registry.add("spring.datasource.driver-class-name", MYSQL_CONTAINER::getDriverClassName);
        registry.add("spring.jpa.hibernate.ddl-auto", () -> "create");
    }

}

UserRepositoryTest.java

@DataJpaTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
class UserRepositoryTest extends AbstractIntegrationTest {

    @Autowired private UserRepository userRepository;

    @DisplayName("이메일로 유저 조회")
    @Test
    void givenEmail_whenFindByEmail_thenWorksFine() {
        // given
        User user = new User("test@email.com", "password", UserRole.USER);
        userRepository.save(user);

        String email = "test@email.com";

        // when
        Optional<User> result = userRepository.findByEmail(email);

        // then
        assertThat(result).isPresent();
        assertThat(result.get().getUserRole()).isEqualTo(UserRole.USER);
    }

}

UserServiceIntegrationTest.java

@SpringBootTest
class UserServiceIntegrationTest extends AbstractIntegrationTest {
    
    @Autowired private UserService userService;

    @Autowired private UserRepository userRepository;

    @DisplayName("유저 조회")
    @Test
    void givenSavedUser_whenFindUserByEmail_thenReturnUserResponse() {
        // given
        String email = "test@email.com";
        User user = new User(email, "password", UserRole.USER);
        userRepository.save(user);

        // when
        UserResponse response = userService.getUser(1L);

        // then
        assertThat(response.getId()).isEqualTo(1L);
        assertThat(response.getEmail()).isEqualTo("test@email.com");
    }

}

참고

profile
일단 해보자

0개의 댓글