使用 @DynamicPropertySource 的 TestContainers、Spring Webflux、JUnit 5、MySQLR2DBCDatabaseContainer
Posted
技术标签:
【中文标题】使用 @DynamicPropertySource 的 TestContainers、Spring Webflux、JUnit 5、MySQLR2DBCDatabaseContainer【英文标题】:TestContainers, Spring Webflux, JUnit 5, MySQLR2DBCDatabaseContainer using @DynamicPropertySource 【发布时间】: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()
【问题讨论】:
“通过 R2DBC URL 方案启动的数据库容器”对您有用吗? testcontainers.org/modules/databases/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...
我有一些测试容器示例。
通过 R2dbc url 启动 Contrainer,请参阅 this R2dbc MySQL example。
使用 Junit 手动设置,请参阅 this R2dbc PostgresSQL example。
使用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
【讨论】:
以上是关于使用 @DynamicPropertySource 的 TestContainers、Spring Webflux、JUnit 5、MySQLR2DBCDatabaseContainer的主要内容,如果未能解决你的问题,请参考以下文章
无法连接到 SpringTest 中由 TestContainers 创建的容器