【问题标题】:TestContainers, Spring Webflux, JUnit 5, MySQLR2DBCDatabaseContainer using @DynamicPropertySource使用 @DynamicPropertySource 的 TestContainers、Spring Webflux、JUnit 5、MySQLR2DBCDatabaseContainer
【发布时间】:2020-12-09 15:35:17
【问题描述】:

我正在尝试执行以下操作;
但使用 org.testcontainers.containers.MySQLR2DBCDatabaseContainer
谁能告诉我这是如何实现的,因为 MySQLR2DBCDatabaseContainer 似乎没有以下方法:

  • ::getJdbcUrl
  • ::getPassword
  • ::获取用户名
@Testcontainers
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class ApplicationIT {
  @Container
  public static PostgreSQLContainer postgreSQLContainer = new PostgreSQLContainer()
    .withPassword("inmemory")
    .withUsername("inmemory");
  @DynamicPropertySource
  static void postgresqlProperties(DynamicPropertyRegistry registry) {
    registry.add("spring.datasource.url", postgreSQLContainer::getJdbcUrl);
    registry.add("spring.datasource.password", postgreSQLContainer::getPassword);
    registry.add("spring.datasource.username", postgreSQLContainer::getUsername);
  }
  @Test
  public void contextLoads() {
  }
}

【问题讨论】:

标签: java mysql testcontainers spring-data-r2dbc r2dbc


【解决方案1】:

对于您的情况,您应该为 R2dbc 连接而不是 Jdbc 连接创建属性。

您必须手动计算 R2dbc URL 而不是 Jdbc URL。

registry.add("spring.r2dbc.url", () -> "r2dbc:postgresql://"
                + postgreSQLContainer.getHost() + ":" + postgreSQLContainer.getFirstMappedPort()
                + "/" + postgreSQLContainer.getDatabaseName());
registry.add("spring.r2dbc.username", () -> postgreSQLContainer.getUsername());
registry.add("spring.r2dbc.password", () -> postgreSQLContainer.getPassword());

更简单地说,您可以为测试容器创建基于 tc 配置文件的应用程序配置。

# src/test/resources/application-tc.properties
spring.r2dbc.url=r2dbc:tc:mysql:///databasename?TC_IMAGE_TAG=8

url中的tc会自动启动一个testcontaienrs docker。请参阅TestContainers R2dbc support

然后您还可以通过@TestConfiguration 应用一些初始工作(例如,创建模式和插入示例数据)。

@DataR2dbcTest
@TestInstance(TestInstance.Lifecycle.PER_METHOD)
@ActiveProfiles("tc")// activate the `tc` profile.
public class TestcontainersPostRepositoryTest {

    @TestConfiguration
    static class TestConfig {
        @Bean
        public ConnectionFactoryInitializer initializer(ConnectionFactory connectionFactory) {

            ConnectionFactoryInitializer initializer = new ConnectionFactoryInitializer();
            initializer.setConnectionFactory(connectionFactory);

            CompositeDatabasePopulator populator = new CompositeDatabasePopulator();
            populator.addPopulators(new ResourceDatabasePopulator(new ClassPathResource("schema.sql")));
            populator.addPopulators(new ResourceDatabasePopulator(new ClassPathResource("data.sql")));
            initializer.setDatabasePopulator(populator);

            return initializer;
        }
    }

    @Autowired
    DatabaseClient client;

    @Autowired
    PostRepository posts;

//your tests...

我有一些测试容器示例。

  1. 通过 R2dbc url 启动 Contrainer,请参阅 this R2dbc MySQL example

  2. 使用 Junit 手动设置,请参阅 this R2dbc PostgresSQL example

  3. 使用spring初始化器类来初始化一个Container,见this Neo4j Rx example

【讨论】:

    【解决方案2】:

    这实际上有点棘手。如果您使用的是响应式存储库,您应该继续使用MySQLContainer,但您必须更改设置数据源的方式(我的代码略有不同,但我希望足够接近,可以让您了解如何解决您的问题) .请注意使用UserRepositoryIntegrationTest::r2dbcUrl

    @Testcontainers
    @DataR2dbcTest
    class UserRepositoryIntegrationTest {
    
        @Container
        private static MySQLContainer database = new MySQLContainer("mysql:8.0.28");
    
        @DynamicPropertySource
        static void registerDynamicProperties(DynamicPropertyRegistry registry) {
            registry.add("spring.r2dbc.url", UserRepositoryIntegrationTest::r2dbcUrl);
            registry.add("spring.r2dbc.username", database::getUsername);
            registry.add("spring.r2dbc.password", database::getPassword);
    
            registry.add("spring.flyway.url", database::getJdbcUrl);
            registry.add("spring.flyway.user", database::getUsername);
            registry.add("spring.flyway.password", database::getPassword);
        }
    
        private static String r2dbcUrl() {
            return String.format("r2dbc:mysql://%s:%s/%s",
                    database.getContainerIpAddress(),
                    database.getMappedPort(MySQLContainer.MYSQL_PORT),
                    database.getDatabaseName());
        }
    }
    

    你可以看看我的回购;我被困在同一个问题上好几天了:UserRepositoryIntegrationTest.java

    【讨论】:

      猜你喜欢
      • 2022-12-20
      • 1970-01-01
      • 2021-03-15
      • 1970-01-01
      • 2021-08-21
      • 2018-12-12
      • 2019-03-22
      • 2018-04-09
      • 2018-04-15
      相关资源
      最近更新 更多