Loading...
Spring Framework Reference Documentation 7.0.2의 Context Configuration with Test Property Sources의 한국어 번역본입니다.
아래의 경우에 피드백에서 신고해주신다면 반영하겠습니다.
감사합니다 :)
Spring Framework는 property source의 계층 구조를 가진 environment 개념을 1급으로
지원하며, test 전용 property source로 integration test를 구성할 수 있습니다.
@Configuration class에서 사용하는 @PropertySource 어노테이션과는 달리,
test class에서 @TestPropertySource 어노테이션을 선언하여 test properties file의
resource location이나 inline된 properties를 선언할 수 있습니다.
이러한 test property source는 어노테이션이 달린 integration test를 위해 로드되는
ApplicationContext의 Environment에 있는 PropertySources 집합에 추가됩니다.
@TestPropertySource는 어떤 구현의SmartContextLoaderSPI와도 함께 사용할 수 있지만, 오래된ContextLoaderSPI의 구현과는 함께 사용할 수 없습니다.SmartContextLoader의 구현은MergedContextConfiguration의getPropertySourceDescriptors()와getPropertySourceProperties()메서드를 통해 merge된 test property source 값에 접근할 수 있습니다.
@TestPropertySource의 locations 또는 value attribute를 사용하여 test
properties file을 구성할 수 있습니다.
기본적으로, 전통적인 java.util.Properties file format과 XML 기반
java.util.Properties file format이 모두 지원됩니다. 예를 들어,
"classpath:/com/example/test.properties" 또는 "file:///path/to/file.xml" 등이
있습니다. Spring Framework 6.1부터는 @TestPropertySource의 factory attribute를
통해 custom PropertySourceFactory를 구성하여 JSON, YAML 등과 같은 다른 file
format을 지원할 수 있습니다.
각 path는 Spring Resource로 해석됩니다. 일반적인 path(예를 들어,
"test.properties")는 test class가 정의된 package를 기준으로 하는 classpath
resource로 처리됩니다. 슬래시로 시작하는 path는 절대 classpath resource로
처리됩니다(예: "/org/example/test.xml"). URL을 참조하는 path(예를 들어,
classpath:, file:, http:로 prefix된 path)는 지정된 resource protocol을
사용하여 로드됩니다.
path에 있는 property placeholder(예: ${…})는 Environment를 기준으로
resolve됩니다.
Spring Framework 6.1부터는 resource location pattern도 지원됩니다. 예를 들어,
"classpath*:/config/*.properties" 등이 있습니다.
다음 예제는 test properties file을 사용합니다:
1@ContextConfiguration 2@TestPropertySource("/test.properties") // (1) 3class MyIntegrationTests { 4 // class body... 5} 6// Copied!
| 1 | 절대 path를 가진 properties file 지정. |
1@ContextConfiguration 2@TestPropertySource("/test.properties") // (1) 3class MyIntegrationTests { 4 // class body... 5} 6// Copied!
| 1 | 절대 path를 가진 properties file 지정. |
다음 예제와 같이 @TestPropertySource의 properties attribute를 사용하여
key-value pair 형식의 inline된 properties를 구성할 수 있습니다. 모든 key-value
pair는 하나의 test PropertySource로서 둘러싼 Environment에 추가되며, 가장
높은 precedence를 가집니다.
key-value pair에 대해 지원되는 syntax는 Java properties file의 entry에 대해 정의된 syntax와 동일합니다:
key=valuekey:valuekey valueproperties는 위의 어떤 syntax variant와 key와 value 사이의 임의의 개수의 공백을 사용하여 정의할 수 있지만, test suite 전체에서 하나의 syntax variant와 일관된 공백을 사용하는 것이 좋습니다. 예를 들어, 항상
key= value,key=value대신key = value를 사용하는 것을 고려하십시오. 마찬가지로, text block을 사용하여 inline된 properties를 정의하는 경우 test suite 전체에서 inline된 properties에 대해 일관되게 text block을 사용해야 합니다. 그 이유는 제공한 정확한 문자열이 context cache의 key를 결정하는 데 사용되기 때문입니다. 결과적으로 context cache의 이점을 얻으려면 inline된 properties를 일관되게 정의해야 합니다.
다음 예제는 두 개의 inline된 properties를 설정합니다:
1@ContextConfiguration 2@TestPropertySource(properties = {"timezone = GMT", "port = 4242"}) // (1) 3class MyIntegrationTests { 4 // class body... 5} 6// Copied!
| 1 | string array를 통해 두 개의 properties 설정. |
1@ContextConfiguration 2@TestPropertySource(properties = ["timezone = GMT", "port = 4242"]) // (1) 3class MyIntegrationTests { 4 // class body... 5} 6// Copied!
| 1 | string array를 통해 두 개의 properties 설정. |
Spring Framework 6.1부터는 _text block_을 사용하여 하나의 String에 여러 개의
inline된 properties를 정의할 수 있습니다. 다음 예제는 text block을 사용하여 두
개의 inline된 properties를 설정합니다:
1@ContextConfiguration 2@TestPropertySource(properties = """ 3 timezone = GMT 4 port = 4242 5 """) // (1) 6class MyIntegrationTests { 7 // class body... 8} 9// Copied!
| 1 | text block을 통해 두 개의 properties 설정. |
1@ContextConfiguration 2@TestPropertySource(properties = [""" 3 timezone = GMT 4 port = 4242 5 """]) // (1) 6class MyIntegrationTests { 7 // class body... 8} 9// Copied!
| 1 | text block을 통해 두 개의 properties 설정. |
@TestPropertySource는 _repeatable annotation_으로 사용할 수 있습니다. 즉, 하나의 test class에 대해 여러 개의@TestPropertySource선언을 가질 수 있으며, 이후의@TestPropertySource어노테이션의locations와properties가 이전@TestPropertySource어노테이션의locations와properties를 override합니다. 또한, 각각이@TestPropertySource로 meta-annotate된 여러 개의 composed 어노테이션을 test class에 선언할 수 있으며, 그러한 모든@TestPropertySource선언은 test property source에 기여하게 됩니다. 직접적으로 존재하는@TestPropertySource어노테이션은 항상 meta-present@TestPropertySource어노테이션보다 우선합니다. 다시 말해, 직접적으로 존재하는@TestPropertySource어노테이션의locations와properties는 메타 어노테이션으로 사용된@TestPropertySource어노테이션의locations와properties를 override합니다.
@TestPropertySource가 빈 어노테이션(즉, locations 또는 properties
attribute에 대한 명시적인 값 없이)으로 선언된 경우, 어노테이션을 선언한 class를
기준으로 default properties file을 탐지하려는 시도가 수행됩니다.
예를 들어,
어노테이션이 달린 test class가 com.example.MyTest인 경우, 해당하는 default
properties file은 classpath:com/example/MyTest.properties입니다. default를
탐지할 수 없는 경우 IllegalStateException이 발생합니다.
test properties는 운영 체제의 environment, Java system properties 또는
@PropertySource를 사용하여 선언적으로나 programmatically하게 애플리케이션에서
추가한 property source에 정의된 properties보다 높은 precedence를 가집니다. 따라서
test properties는 system 및 애플리케이션 property source에서 로드된 properties를
선택적으로 override하는 데 사용할 수 있습니다.
또한, inline된 properties는
resource location에서 로드된 properties보다 높은 precedence를 가집니다. 그러나
@DynamicPropertySource를
통해 등록된 properties는 @TestPropertySource를 통해 로드된 properties보다 더
높은 precedence를 가집니다.
다음 예제에서 timezone과 port properties 및 "/test.properties"에 정의된
모든 properties는 system 및 애플리케이션 property source에 정의된 동일한 이름의
properties를 override합니다. 또한 "/test.properties" file이 timezone과
port properties에 대한 entry를 정의하는 경우, 이는 properties attribute를
사용하여 선언된 inline된 properties에 의해 override됩니다.
다음 예제는 file과 inline 양쪽에 properties를 지정하는 방법을 보여줍니다:
1@ContextConfiguration 2@TestPropertySource( 3 locations = "/test.properties", 4 properties = {"timezone = GMT", "port = 4242"} 5) 6class MyIntegrationTests { 7 // class body... 8} 9// Copied!
1@ContextConfiguration 2@TestPropertySource( 3 "/test.properties", 4 properties = ["timezone = GMT", "port = 4242"] 5) 6class MyIntegrationTests { 7 // class body... 8} 9// Copied!
@TestPropertySource는 boolean inheritLocations 및 inheritProperties
attribute를 지원하며, 이는 superclass에서 선언된 properties file에 대한 resource
location과 inline된 properties를 상속할지 여부를 나타냅니다. 두 flag의 기본
값은 true입니다. 이는 test class가 모든 superclass에서 선언된 location과
inline된 properties를 상속한다는 것을 의미합니다.
구체적으로, test class에 대한 location과 inline된 properties는 superclass에서 선언된 location과 inline된 properties에 append됩니다. 따라서 subclass는 location과 inline된 properties를 확장할 수 있는 선택권을 가집니다. 나중에 나타나는 properties는 이전에 나타나는 동일한 이름의 properties를 shadow(즉, override)한다는 점에 유의해야 합니다. 또한, 앞서 언급한 precedence 규칙은 상속된 test property source에도 적용됩니다.
@TestPropertySource의 inheritLocations 또는 inheritProperties attribute가
false로 설정된 경우, 해당 test class에 대한 location 또는 inline된 properties는
각각 superclass에 의해 정의된 구성을 shadow하고 사실상 대체합니다.
test configuration은 enclosing class로부터도 상속될 수 있습니다. 자세한 내용은
@Nestedtest class configuration을 참조하십시오.
다음 예제에서 BaseTest에 대한 ApplicationContext는 test property source로
base.properties file만을 사용하여 로드됩니다. 반대로, ExtendedTest에 대한
ApplicationContext는 test property source location으로 base.properties와
extended.properties file을 사용하여 로드됩니다.
다음 예제는 properties
file을 사용하여 subclass와 superclass 모두에 properties를 정의하는 방법을
보여줍니다:
1@TestPropertySource("base.properties") 2@ContextConfiguration 3class BaseTest { 4 // ... 5} 6 7@TestPropertySource("extended.properties") 8@ContextConfiguration 9class ExtendedTest extends BaseTest { 10 // ... 11} 12// Copied!
1@TestPropertySource("base.properties") 2@ContextConfiguration 3open class BaseTest { 4 // ... 5} 6 7@TestPropertySource("extended.properties") 8@ContextConfiguration 9class ExtendedTest : BaseTest() { 10 // ... 11} 12// Copied!
다음 예제에서 BaseTest에 대한 ApplicationContext는 inline된 key1
property만을 사용하여 로드됩니다. 반대로, ExtendedTest에 대한
ApplicationContext는 inline된 key1과 key2 properties를 사용하여
로드됩니다.
다음 예제는 inline properties를 사용하여 subclass와 superclass 모두에 properties를 정의하는 방법을 보여줍니다:
1@TestPropertySource(properties = "key1 = value1") 2@ContextConfiguration 3class BaseTest { 4 // ... 5} 6 7@TestPropertySource(properties = "key2 = value2") 8@ContextConfiguration 9class ExtendedTest extends BaseTest { 10 // ... 11} 12// Copied!
1@TestPropertySource(properties = ["key1 = value1"]) 2@ContextConfiguration 3open class BaseTest { 4 // ... 5} 6 7@TestPropertySource(properties = ["key2 = value2"]) 8@ContextConfiguration 9class ExtendedTest : BaseTest() { 10 // ... 11} 12// Copied!
Context Configuration with Environment Profiles
Context Configuration with Dynamic Property Sources