반응형

설명

  • 아래에서는 docker-compose.yml를 활용하여 MySQL과 Redis 컨테이너를 띄워 테스트하는 예제를 설명한다.
  • 테스트마다 docker container를 띄우는 방식은 속도가 느리므로, 전체 테스트 실행 전에 한 번 띄우고 테스트가 모두 종료되면 컨테이너가 종료되는 방식을 예제로 작성.

의존성 추가

implementation("org.springframework.boot:spring-boot-starter-jdbc")
implementation("org.springframework.boot:spring-boot-starter-data-redis")
implementation("mysql:mysql-connector-java:8.0.33")

testImplementation("org.testcontainers:testcontainers:1.19.1")

~/src/test/resources/sql/table.sql

# Student
DROP TABLE IF EXISTS Student;
CREATE TABLE Student
(
    id   BIGINT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(50) NOT NULL
);

~/src/test/resources/docker-compose.yml

version: "3.3"
volumes:
  mysql_data: { }
  redis_data: { }
services:
  mysql_for_test:
    image: mysql:5.7.44
    platform: linux/amd64 # for mac
    ports:
      - "13306:3306"
    environment:
      TZ: Asia/Seoul
      MYSQL_USER: test
      MYSQL_PASSWORD: 123456
      MYSQL_ROOT_PASSWORD: 123456
      MYSQL_DATABASE: test
    volumes:
      - mysql_data:/var/lib/mysql/
      - ./sql:/docker-entrypoint-initdb.d
    command:
      - "--character-set-server=utf8mb4"
      - "--collation-server=utf8mb4_unicode_ci"
      - "--skip-character-set-client-handshake"
  redis_for_test:
    image: redis:6.0.1
    environment:
      TZ: Asia/Seoul
    ports:
      - "16379:6379"
    volumes:
      - redis_data:/data/

application-test.yml

spring:
  datasource:
    url: jdbc:mysql://localhost:13306/test
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: test
    password: 123456
  data:
    redis:
      host: localhost
      port: 16379

DockerComposeExtension

@AutoScan
class DockerComposeExtension : BeforeProjectListener, AfterProjectListener {
    private val log = LoggerFactory.getLogger(this::class.java)
    private val container = DockerComposeContainer<Nothing>(File("src/test/resources/docker-compose.yml")).apply {
        waitingFor("mysql_for_test", ShellStrategy().withCommand("mysql -u'test' -p'123456' -e'select 1' && sleep 2")) // 접속 가능해질때까지 대기
        waitingFor("redis_for_test", ShellStrategy().withCommand("redis-cli get test"))
    }

    override suspend fun beforeProject() {
        log.info { "[DOCKER_COMPOSE_EXTENSION] start" }
        container.start()
    }

    override suspend fun afterProject() {
        container.stop()
        log.info { "[DOCKER_COMPOSE_EXTENSION] stop" }
    }
}
@ActiveProfiles("test")
@SpringBootTest
class DockerTest(
    private val jdbcTemplate: JdbcTemplate,
    private val stringRedisTemplate: StringRedisTemplate,
) : FunSpec({
    test("jdbc test") {
        jdbcTemplate.execute("INSERT INTO Student (name) VALUES ('tyler')");
        val result = jdbcTemplate.queryForMap("SELECT * FROM Student LIMIT 1")
        result["id"] shouldBe 1
        result["name"] shouldBe "tyler"
    }

    test("redis test") {
        stringRedisTemplate.opsForValue().set("message", "Hello World")
        val value = stringRedisTemplate.opsForValue().get("message")
        value shouldBe "Hello World"
    }
})

참고

반응형

'Development > Kotest' 카테고리의 다른 글

[Kotest] mockk  (0) 2023.11.04
[Kotest] SpringBootTest  (0) 2023.11.04
[Kotest] extensions  (0) 2023.11.04
[Kotest] lifecycle hook  (0) 2023.11.04
[Kotest] isolation modes  (0) 2023.11.04

+ Recent posts