テストプロパティソースを使用したコンテキスト構成
Spring Framework は、プロパティソースの階層を持つ環境の概念に対するファーストクラスのサポートを備えており、テスト固有のプロパティソースを使用して統合テストを構成できます。@Configuration
クラスで使用される @PropertySource
アノテーションとは対照的に、テストクラスで @TestPropertySource
アノテーションを宣言して、テストプロパティファイルまたはインラインプロパティのリソースの場所を宣言できます。これらのテストプロパティソースは、アノテーション付き統合テスト用に読み込まれた ApplicationContext
の Environment
の PropertySources
のセットに追加されます。
|
テストプロパティソースの宣言
@TestPropertySource
の locations
または value
属性を使用して、テストプロパティファイルを構成できます。
デフォルトでは、従来の java.util.Properties
ファイル形式と XML ベースの java.util.Properties
ファイル形式 (たとえば、"classpath:/com/example/test.properties"
または "file:///path/to/file.xml"
) の両方がサポートされています。Spring Framework 6.1 以降、JSON、YAML などの異なるファイル形式をサポートするために、@TestPropertySource
の factory
属性を介してカスタム PropertySourceFactory
を構成できます。
各パスは Spring Resource
として解釈されます。プレーンパス (たとえば、"test.properties"
) は、テストクラスが定義されているパッケージに相対的なクラスパスリソースとして扱われます。スラッシュで始まるパスは、絶対クラスパスリソースとして扱われます (例: "/org/example/test.xml"
)。URL を参照するパス (たとえば、classpath:
、file:
、または http:
というプレフィックスが付いたパス) は、指定されたリソースプロトコルを使用してロードされます。
パス内のプロパティプレースホルダー ( ${…}
など) は、Environment
に対して解決されます。
Spring Framework 6.1 以降、リソースの場所のパターン ( "classpath*:/config/*.properties"
など) もサポートされています。
次の例では、テストプロパティファイルを使用しています。
Java
Kotlin
@ContextConfiguration
@TestPropertySource("/test.properties") (1)
class MyIntegrationTests {
// class body...
}
1 | 絶対パスでプロパティファイルを指定します。 |
@ContextConfiguration
@TestPropertySource("/test.properties") (1)
class MyIntegrationTests {
// class body...
}
1 | 絶対パスでプロパティファイルを指定します。 |
次の例に示すように、@TestPropertySource
の properties
属性を使用して、キーと値のペアの形式でインラインプロパティを構成できます。すべてのキーと値のペアは、最高の優先順位を持つ単一のテスト PropertySource
として、包含 Environment
に追加されます。
キーと値のペアでサポートされている構文は、Java プロパティファイルのエントリに定義されている構文と同じです。
key=value
key:value
key value
プロパティは、上記の構文バリアントのいずれか、およびキーと値の間に任意の数のスペースを使用して定義できますが、テストスイート内で 1 つの構文バリアントと一貫したスペースを使用することをお勧めします。たとえば、常に その理由は、コンテキストキャッシュのキーを決定するために、指定した正確な文字列が使用されるためです。コンテキストキャッシュの利点を活用するには、インラインプロパティを一貫して定義する必要があります。 |
次の例では、2 つのインラインプロパティを設定します。
Java
Kotlin
@ContextConfiguration
@TestPropertySource(properties = {"timezone = GMT", "port = 4242"}) (1)
class MyIntegrationTests {
// class body...
}
1 | 文字列の配列を介して 2 つのプロパティを設定します。 |
@ContextConfiguration
@TestPropertySource(properties = ["timezone = GMT", "port = 4242"]) (1)
class MyIntegrationTests {
// class body...
}
1 | 文字列の配列を介して 2 つのプロパティを設定します。 |
Spring Framework 6.1 以降では、テキストブロックを使用して、単一の String
で複数のインラインプロパティを定義できます。次の例では、テキストブロックを使用して 2 つのインラインプロパティを設定します。
Java
Kotlin
@ContextConfiguration
@TestPropertySource(properties = """
timezone = GMT
port = 4242
""") (1)
class MyIntegrationTests {
// class body...
}
1 | テキストブロックを介して 2 つのプロパティを設定します。 |
@ContextConfiguration
@TestPropertySource(properties = ["""
timezone = GMT
port = 4242
"""]) (1)
class MyIntegrationTests {
// class body...
}
1 | テキストブロックを介して 2 つのプロパティを設定します。 |
Spring Framework 5.2 以降、 さらに、それぞれが 直接存在する |
デフォルトのプロパティファイルの検出
@TestPropertySource
が空のアノテーションとして宣言されている場合(つまり、locations
または properties
属性の明示的な値がない場合)、アノテーションを宣言したクラスに関連するデフォルトのプロパティファイルを検出しようとします。例: アノテーション付きテストクラスが com.example.MyTest
の場合、対応するデフォルトプロパティファイルは classpath:com/example/MyTest.properties
です。デフォルトを検出できない場合、IllegalStateException
がスローされます。
優先順位
テストプロパティは、オペレーティングシステムの環境、Java システムプロパティ、@PropertySource
を使用してプログラムによってアプリケーションによって宣言的に追加されたプロパティソースで定義されたものよりも優先されます。テストプロパティを使用して、システムおよびアプリケーションプロパティソースからロードされたプロパティを選択的にオーバーライドできます。さらに、インライン化されたプロパティは、リソースの場所から読み込まれたプロパティよりも優先されます。ただし、@DynamicPropertySource
を介して登録されたプロパティは、@TestPropertySource
を介してロードされたプロパティよりも優先されることに注意してください。
次の例では、timezone
プロパティと port
プロパティ、および "/test.properties"
で定義されたプロパティは、システムおよびアプリケーションプロパティソースで定義された同じ名前のプロパティをオーバーライドします。さらに、"/test.properties"
ファイルが timezone
および port
プロパティのエントリを定義する場合、properties
属性を使用して宣言されたインラインプロパティによってオーバーライドされます。次の例は、ファイルとインラインの両方でプロパティを指定する方法を示しています。
Java
Kotlin
@ContextConfiguration
@TestPropertySource(
locations = "/test.properties",
properties = {"timezone = GMT", "port = 4242"}
)
class MyIntegrationTests {
// class body...
}
@ContextConfiguration
@TestPropertySource("/test.properties",
properties = ["timezone = GMT", "port = 4242"]
)
class MyIntegrationTests {
// class body...
}
テストプロパティソースの継承とオーバーライド
@TestPropertySource
は、スーパークラスによって宣言されたプロパティファイルとインラインプロパティのリソースの場所を継承する必要があるかどうかを示すブール inheritLocations
および inheritProperties
属性をサポートしています。両方のフラグのデフォルト値は true
です。つまり、テストクラスは、スーパークラスによって宣言された場所とインラインプロパティを継承します。具体的には、テストクラスの場所とインラインプロパティは、スーパークラスによって宣言された場所とインラインプロパティに追加されます。サブクラスには、場所とインラインプロパティを継承するオプションがあります。後で表示されるプロパティは、以前に表示される同じ名前のプロパティをシャドウ(つまり、オーバーライド)することに注意してください。さらに、前述の優先規則は、継承されたテストプロパティソースにも適用されます。
@TestPropertySource
の inheritLocations
または inheritProperties
属性が false
に設定されている場合、テストクラスシャドウの場所またはインラインプロパティはそれぞれ、スーパークラスによって定義された構成を効果的に置き換えます。
Spring Framework 5.3 以降、テスト構成は、囲んでいるクラスから継承することもできます。詳細については、@Nested テストクラスの構成を参照してください。 |
次の例では、BaseTest
の ApplicationContext
は、base.properties
ファイルのみをテストプロパティソースとして使用してロードされます。対照的に、ExtendedTest
の ApplicationContext
は、base.properties
および extended.properties
ファイルをテストプロパティソースの場所として使用してロードされます。次の例は、properties
ファイルを使用して、サブクラスとそのスーパークラスの両方でプロパティを定義する方法を示しています。
Java
Kotlin
@TestPropertySource("base.properties")
@ContextConfiguration
class BaseTest {
// ...
}
@TestPropertySource("extended.properties")
@ContextConfiguration
class ExtendedTest extends BaseTest {
// ...
}
@TestPropertySource("base.properties")
@ContextConfiguration
open class BaseTest {
// ...
}
@TestPropertySource("extended.properties")
@ContextConfiguration
class ExtendedTest : BaseTest() {
// ...
}
次の例では、インライン key1
プロパティのみを使用して、BaseTest
の ApplicationContext
がロードされます。対照的に、ExtendedTest
の ApplicationContext
は、インラインの key1
および key2
プロパティを使用してロードされます。次の例は、インラインプロパティを使用して、サブクラスとそのスーパークラスの両方でプロパティを定義する方法を示しています。
Java
Kotlin
@TestPropertySource(properties = "key1 = value1")
@ContextConfiguration
class BaseTest {
// ...
}
@TestPropertySource(properties = "key2 = value2")
@ContextConfiguration
class ExtendedTest extends BaseTest {
// ...
}
@TestPropertySource(properties = ["key1 = value1"])
@ContextConfiguration
open class BaseTest {
// ...
}
@TestPropertySource(properties = ["key2 = value2"])
@ContextConfiguration
class ExtendedTest : BaseTest() {
// ...
}