動的プロパティソースを使用したコンテキスト構成
Spring、TestContext、フレームワークは、DynamicPropertyRegistry
、@DynamicPropertySource
アノテーション、および DynamicPropertyRegistrar
API を介して動的プロパティのサポートを提供します。
動的プロパティソースインフラストラクチャは、もともと、Testcontainers (英語) ベースのテストのプロパティを Spring 統合テストに簡単に公開できるようにするために設計されました。ただし、これらの機能は、テストの |
優先順位
動的プロパティは、@TestPropertySource
、オペレーティングシステムの環境、Java システムプロパティ、アプリケーションによって宣言的に @PropertySource
を使用して、またはプログラムによって追加されたプロパティソースからロードされたプロパティよりも優先されます。動的プロパティを使用して、@TestPropertySource
、システムプロパティソース、アプリケーションプロパティソースを介してロードされたプロパティを選択的にオーバーライドできます。
DynamicPropertyRegistry
DynamicPropertyRegistry
は、Environment
に名前と値のペアを追加するために使用されます。値は動的であり、プロパティが解決されたときにのみ呼び出される Supplier
を介して提供されます。通常、メソッド参照を使用して値を指定します。次のセクションでは、DynamicPropertyRegistry
の使用方法の例を示します。
@DynamicPropertySource
クラスレベルで適用される @TestPropertySource
アノテーションとは対照的に、統合テストクラスの static
メソッドに @DynamicPropertySource
を適用して、統合テスト用にロードされた ApplicationContext
の Environment
内の PropertySources
のセットに動的な値を持つプロパティを追加できます。
@DynamicPropertySource
でアノテーションが付けられた統合テストクラスのメソッドは、static
である必要があり、単一の DynamicPropertyRegistry
引数を受け入れる必要があります。詳細については、DynamicPropertyRegistry
のクラスレベルの javadoc を参照してください。
基本クラスで |
次の例では、Testcontainers プロジェクトを使用して、Spring ApplicationContext
の外部にある Redis コンテナーを管理します。管理対象の Redis コンテナーの IP アドレスとポートは、redis.host
および redis.port
プロパティを介して、テストの ApplicationContext
内のコンポーネントで使用できるようになります。これらのプロパティは、Spring の Environment
抽象化を介してアクセスすることも、それぞれ @Value("${redis.host}")
および @Value("${redis.port}")
を介して Spring 管理コンポーネントに直接挿入することもできます。
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
メソッドを実装する代わりに、テストの ApplicationContext
内の Bean として DynamicPropertyRegistrar
API の実装を登録できます。これにより、@DynamicPropertySource
メソッドでは不可能な追加のユースケースをサポートできます。例: DynamicPropertyRegistrar
自体は ApplicationContext
内の Bean であるため、コンテキスト内の他の Bean と対話し、それらの Bean から取得される動的プロパティを登録できます。
DynamicPropertyRegistrar
インターフェースを実装するテストの ApplicationContext
内の Bean はすべて自動的に検出され、シングルトンの事前インスタンス化フェーズの前に積極的に初期化され、そのような Bean の accept()
メソッドは、レジストラに代わって実際の動的プロパティ登録を実行する DynamicPropertyRegistry
で呼び出されます。
他の Bean とのやり取りにより、他の Bean とその依存関係が積極的に初期化されます。 |
次の例は、ApiServer
Bean の動的プロパティを登録するラムダ式として DynamicPropertyRegistrar
を実装する方法を示しています。api.url
プロパティは、Spring の Environment
抽象化を介してアクセスするか、他の Spring 管理コンポーネントに直接注入することができます (たとえば、@Value("${api.url}")
を介して)。また、api.url
プロパティの値は、ApiServer
Bean から動的に取得されます。
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)
}
}