0
0

Testcontainersで複数DBに接続

Posted at

https://start.spring.io/ を使用して適当なプロジェクトを作成する。複数DBとしてmysqlとpostgresqlに接続するのでそれら関連の依存性を追加する。

build.gradle
plugins {
	id 'java'
	id 'org.springframework.boot' version '3.3.2'
	id 'io.spring.dependency-management' version '1.1.6'
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'

java {
	toolchain {
		languageVersion = JavaLanguageVersion.of(17)
	}
}

repositories {
	mavenCentral()
}

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-jdbc'
	
	runtimeOnly 'com.mysql:mysql-connector-j'
	runtimeOnly 'org.postgresql:postgresql'
	
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
	testImplementation 'org.springframework.boot:spring-boot-testcontainers'
	
	testImplementation 'org.testcontainers:junit-jupiter'
	testImplementation 'org.testcontainers:mysql'
	testImplementation 'org.testcontainers:postgresql'
	
	testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}

tasks.named('test') {
	useJUnitPlatform()
}

テストコードを作成する。

import javax.sql.DataSource;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.jdbc.core.simple.JdbcClient;
import org.springframework.test.context.DynamicPropertyRegistry;
import org.springframework.test.context.DynamicPropertySource;
import org.testcontainers.containers.MySQLContainer;
import org.testcontainers.containers.PostgreSQLContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;

@SpringBootTest
@Testcontainers
@EnableAutoConfiguration(exclude = DataSourceAutoConfiguration.class)
class AppTest {

  @Container
  static MySQLContainer<?> mysql = new MySQLContainer<>("mysql:5.7.34");

  @Container
  static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:16-alpine");

  @DynamicPropertySource
  static void registerProperties(DynamicPropertyRegistry registry) {
    registry.add("spring.datasource.mysql.url", () -> mysql.getJdbcUrl());
    registry.add("spring.datasource.mysql.username", () -> mysql.getUsername());
    registry.add("spring.datasource.mysql.password", () -> mysql.getPassword());

    registry.add("spring.datasource.postgres.url", () -> postgres.getJdbcUrl());
    registry.add("spring.datasource.postgres.username", () -> postgres.getUsername());
    registry.add("spring.datasource.postgres.password", () -> postgres.getPassword());
  }

  @TestConfiguration
  static class TestConfig {

    @Bean
    @ConfigurationProperties("spring.datasource.mysql")
    public DataSourceProperties mysqlDataSourceProperties() {
      return new DataSourceProperties();
    }

    @Bean
    @ConfigurationProperties("spring.datasource.postgres")
    public DataSourceProperties postgresDataSourceProperties() {
      return new DataSourceProperties();
    }

    @Bean
    public DataSource mysqlDataSource() {
      return mysqlDataSourceProperties()
          .initializeDataSourceBuilder()
          .build();
    }

    @Bean
    public DataSource postgresDataSource() {
      return postgresDataSourceProperties()
          .initializeDataSourceBuilder()
          .build();
    }
  }

  @Test
  void test(
      @Qualifier("mysqlDataSource") DataSource mysqlDataSource,
      @Qualifier("postgresDataSource") DataSource postgresDataSource) {
    Integer v1 = JdbcClient.create(mysqlDataSource).sql("select cast('1' AS unsigned)")
        .query(Integer.class).single();
    System.out.println("mysql:" + v1);
    Integer v2 = JdbcClient.create(postgresDataSource).sql("select cast('1' AS int)")
        .query(Integer.class).single();
    System.out.println("postgres:" + v2);
  }
}

スマートなやり方が分からなかったので、@DynamicPropertySourceで動的にデータソース関連プロパティを単純に書き換えている。@ServiceConnectionが使用できそうな気もするけど、auto-configを見ると単一DBにしか対応してないのかな……という感じもしたが良く分からない。springのConnectionDetailsの仕組みを利用しているので、これをもう少し調べれば何とかなるかな……という気もする。これ以上は調べきれなかったので一旦これで投稿してしまう。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0