動的プロパティソースを使用したコンテキスト構成
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)
}
}