動的プロパティソースを使用したコンテキスト構成

Spring Framework 5.2.5 以降、TestContext フレームワークは、@DynamicPropertySource アノテーションを介して動的プロパティのサポートを提供します。このアノテーションは、統合テスト用にロードされた ApplicationContext の Environment 内の PropertySources のセットに動的な値を持つプロパティを追加する必要がある統合テストで使用できます。

@DynamicPropertySource アノテーションとそのサポートインフラストラクチャは、当初、Testcontainers (英語) ベースのテストのプロパティを Spring 統合テストに簡単に公開できるように設計されました。ただし、この機能は、テストの ApplicationContext 外でライフサイクルが維持される外部リソースの任意の形式で使用することもできます。

クラスレベルで適用される @TestPropertySource アノテーションとは対照的に、@DynamicPropertySource は、Environment名前と値のペアを追加するために使用される単一の DynamicPropertyRegistry 引数を受け入れる static メソッドに適用される必要があります。値は動的であり、プロパティが解決されたときにのみ呼び出される Supplier を介して提供されます。通常、メソッド参照は値を提供するために使用されます。次の例では、Testcontainers プロジェクトを使用して Spring ApplicationContext 外の Redis コンテナーを管理しています。管理された Redis コンテナーの IP アドレスとポートは、redis.host および redis.port プロパティを介して、テストの ApplicationContext 内のコンポーネントで利用できるようになります。これらのプロパティは、Spring の Environment 抽象化を介してアクセスするか、たとえば、それぞれ @Value("${redis.host}") および @Value("${redis.port}") を介して、Spring 管理のコンポーネントに直接注入できます。

基本クラスで @DynamicPropertySource を使用し、動的プロパティがサブクラス間で変更されるためにサブクラスでのテストが失敗することがわかった場合、各サブクラスが正しい動的プロパティを持つ独自の ApplicationContext を取得するように、基本クラスに @DirtiesContext のアノテーションを付ける必要があります。

  • 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 ...

}

優先順位

動的プロパティは、@TestPropertySource、オペレーティングシステムの環境、Java システムプロパティ、アプリケーションによって宣言的に @PropertySource を使用して、またはプログラムによって追加されたプロパティソースからロードされたプロパティよりも優先されます。動的プロパティを使用して、@TestPropertySource、システムプロパティソース、アプリケーションプロパティソースを介してロードされたプロパティを選択的にオーバーライドできます。