此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Framework 6.2.0! |
使用动态属性源的上下文配置
Spring TestContext 框架通过DynamicPropertyRegistry
这@DynamicPropertySource
注解和DynamicPropertyRegistrar
应用程序接口。
动态属性源基础架构最初设计为允许属性
从基于 Testcontainers 的测试中轻松暴露给 Spring
集成测试。但是,这些功能可以与任何形式的外部资源一起使用
其生命周期在测试的 |
优先
动态属性的优先级高于从@TestPropertySource
,
作系统的环境、Java 系统属性或由
应用程序使用@PropertySource
或以编程方式。因此
动态属性可用于选择性地覆盖通过@TestPropertySource
、系统属性源和应用程序属性源。
DynamicPropertyRegistry
一个DynamicPropertyRegistry
用于将名称-值对添加到Environment
.
值是动态的,并通过Supplier
仅当属性
已解决。通常,方法引用用于提供值。以下内容
各节提供了如何使用DynamicPropertyRegistry
.
@DynamicPropertySource
与@TestPropertySource
注解,以及@DynamicPropertySource
可应用于static
方法,以便使用 dynamic
values 设置为PropertySources
在Environment
对于ApplicationContext
loaded 进行集成测试。
集成测试类中带有@DynamicPropertySource
必须
是static
并且必须接受单个DynamicPropertyRegistry
论点。请参阅
的类级 javadocDynamicPropertyRegistry
了解更多详情。
如果您使用 |
以下示例使用 Testcontainers 项目来管理外部的 Redis 容器
SpringApplicationContext
.托管式 Redis 的 IP 地址和端口
容器可供测试的ApplicationContext
通过redis.host
和redis.port
性能。这些属性可以通过 Spring 的Environment
抽象或直接注入到 Spring 管理的组件中 —— 用于
示例,通过@Value("${redis.host}")
和@Value("${redis.port}")
分别。
-
Java
-
Kotlin
@SpringJUnitConfig(/* ... */)
@Testcontainers
class ExampleIntegrationTests {
@Container
static GenericContainer redis =
new GenericContainer("redis:5.0.3-alpine").withExposedPorts(6379);
@DynamicPropertySource
static void redisProperties(DynamicPropertyRegistry registry) {
registry.add("redis.host", redis::getHost);
registry.add("redis.port", redis::getFirstMappedPort);
}
// tests ...
}
@SpringJUnitConfig(/* ... */)
@Testcontainers
class ExampleIntegrationTests {
companion object {
@Container
@JvmStatic
val redis: GenericContainer =
GenericContainer("redis:5.0.3-alpine").withExposedPorts(6379)
@DynamicPropertySource
@JvmStatic
fun redisProperties(registry: DynamicPropertyRegistry) {
registry.add("redis.host", redis::getHost)
registry.add("redis.port", redis::getFirstMappedPort)
}
}
// tests ...
}
DynamicPropertyRegistrar
作为实施的替代方案@DynamicPropertySource
Integration Test 中的方法
类中,您可以注册DynamicPropertyRegistrar
API 作为 bean
在测试的ApplicationContext
.这样做可以支持其他用途
无法使用@DynamicPropertySource
方法。例如,由于DynamicPropertyRegistrar
本身就是ApplicationContext
,它可以交互
替换为上下文中的其他 bean,并注册源自
那些豆子。
测试中的任何 beanApplicationContext
实现DynamicPropertyRegistrar
接口将在单例之前被自动检测并预先初始化
pre-instantiation 阶段和accept()
此类 bean 的方法将使用DynamicPropertyRegistry
执行实际的动态属性注册
代表注册商。
与其他 bean 的任何交互都会导致对其他 bean 的 Eager 初始化 bean 及其依赖项。 |
以下示例演示了如何实现DynamicPropertyRegistrar
作为
Lambda 表达式,该表达式为ApiServer
豆。这api.url
属性可以通过 Spring 的Environment
abstraction 或 injected
直接进入其他 Spring 管理的组件 —— 例如,通过@Value("${api.url}")
,
和api.url
属性将从ApiServer
豆。
-
Java
-
Kotlin
@Configuration
class TestConfig {
@Bean
ApiServer apiServer() {
return new ApiServer();
}
@Bean
DynamicPropertyRegistrar apiPropertiesRegistrar(ApiServer apiServer) {
return registry -> registry.add("api.url", apiServer::getUrl);
}
}
@Configuration
class TestConfig {
@Bean
fun apiServer(): ApiServer {
return ApiServer()
}
@Bean
fun apiPropertiesRegistrar(apiServer: ApiServer): DynamicPropertyRegistrar {
return registry -> registry.add("api.url", apiServer::getUrl)
}
}