1. 概述
本教程將探討多種方法來覆蓋 Spring 測試中的屬性。
Spring 實際上提供了多種解決方案來解決這個問題,因此這裏有很多值得探索的內容。
2. 依賴項
為了使用 Spring 測試,我們需要添加一個測試依賴:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>這個依賴項還包括 JUnit 5。
3. 安裝配置
首先,我們將創建一個在應用程序中使用的類,該類將使用我們的屬性:
@Component
public class PropertySourceResolver {
@Value("${example.firstProperty}") private String firstProperty;
@Value("${example.secondProperty}") private String secondProperty;
public String getFirstProperty() {
return firstProperty;
}
public String getSecondProperty() {
return secondProperty;
}
}接下來,我們將為它們分配值。我們可以通過在 src/main/resources 目錄下創建 application.properties 文件來完成此操作。
example.firstProperty=defaultFirst
example.secondProperty=defaultSecond4. 覆蓋屬性文件
現在我們將通過將屬性文件放在測試資源中來覆蓋屬性。該文件必須在與默認文件相同的類路徑上。
此外,它應該包含默認文件中指定的所有屬性鍵。因此,我們將application.properties文件添加到src/test/resources中:
example.firstProperty=file
example.secondProperty=file讓我們也添加一個測試,該測試將使用我們的解決方案:
@SpringBootTest
public class TestResourcePropertySourceResolverIntegrationTest {
@Autowired private PropertySourceResolver propertySourceResolver;
@Test
public void shouldTestResourceFile_overridePropertyValues() {
String firstProperty = propertySourceResolver.getFirstProperty();
String secondProperty = propertySourceResolver.getSecondProperty();
assertEquals("file", firstProperty);
assertEquals("file", secondProperty);
}
}此方法在我們需要從文件中覆蓋多個屬性時非常有效。
如果我們在文件中沒有放入 example.secondProperty,則應用程序上下文將無法發現該屬性。
5. Spring 配置文件
在本節中,我們將學習如何通過使用 Spring 配置文件來處理我們的問題。 與之前的方法不同,這種方法會將默認文件和配置文件中的屬性合併。
首先,讓我們在 src/test/resources 目錄下創建一個 application-test.properties 文件。
example.firstProperty=profile然後,我們將創建一個測試,該測試將使用 test 配置文件:
@SpringBootTest
@ActiveProfiles("test")
public class ProfilePropertySourceResolverIntegrationTest {
@Autowired private PropertySourceResolver propertySourceResolver;
@Test
public void shouldProfiledProperty_overridePropertyValues() {
String firstProperty = propertySourceResolver.getFirstProperty();
String secondProperty = propertySourceResolver.getSecondProperty();
assertEquals("profile", firstProperty);
assertEquals("defaultSecond", secondProperty);
}
}這種方法允許我們同時使用默認值和測試值。因此,當我們需要從文件中覆蓋多個屬性,同時仍然使用默認值時,這是一種非常好的方法。
關於 Spring 配置文件,請參閲我們的 Spring 配置文件 文章。
6. <em @SpringBootTest
另一種覆蓋屬性值的方法是使用 <em @SpringBootTest 註解:
@SpringBootTest(properties = { "example.firstProperty=annotation" })
public class SpringBootPropertySourceResolverIntegrationTest {
@Autowired private PropertySourceResolver propertySourceResolver;
@Test
public void shouldSpringBootTestAnnotation_overridePropertyValues() {
String firstProperty = propertySourceResolver.getFirstProperty();
String secondProperty = propertySourceResolver.getSecondProperty();
Assert.assertEquals("annotation", firstProperty);
Assert.assertEquals("defaultSecond", secondProperty);
}
}如我們所見,example.firstProperty 已經被覆蓋,而 example.secondProperty 尚未被覆蓋。因此,當我們需要僅覆蓋特定屬性進行測試時,這是一種很好的解決方案。這是唯一需要使用 Spring Boot 的方法。
7. TestPropertySourceUtils
在本節中,我們將學習如何通過使用 TestPropertySourceUtils 類來覆蓋屬性,該方法在 ApplicationContextInitializer 中使用。
TestPropertySourceUtils 提供了兩個方法,我們可以用它們來定義不同的屬性值。
讓我們創建一個初始化器類,用於在我們的測試中使用它:
public class PropertyOverrideContextInitializer
implements ApplicationContextInitializer<ConfigurableApplicationContext> {
static final String PROPERTY_FIRST_VALUE = "contextClass";
@Override
public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
TestPropertySourceUtils.addInlinedPropertiesToEnvironment(
configurableApplicationContext, "example.firstProperty=" + PROPERTY_FIRST_VALUE);
TestPropertySourceUtils.addPropertiesFilesToEnvironment(
configurableApplicationContext, "context-override-application.properties");
}
}接下來,我們將 context-override-application.properties 文件添加到 src/test/resources 目錄中。
example.secondProperty=contextFile最後,我們應該創建一個測試類,該類將使用我們的初始化器:
@SpringBootTest
@ContextConfiguration(
initializers = PropertyOverrideContextInitializer.class,
classes = Application.class)
public class ContextPropertySourceResolverIntegrationTest {
@Autowired private PropertySourceResolver propertySourceResolver;
@Test
public void shouldContext_overridePropertyValues() {
final String firstProperty = propertySourceResolver.getFirstProperty();
final String secondProperty = propertySourceResolver.getSecondProperty();
assertEquals(PropertyOverrideContextInitializer.PROPERTY_FIRST_VALUE, firstProperty);
assertEquals("contextFile", secondProperty);
}
}該 example.firstProperty 屬性值已從內聯方法中覆蓋。
該 example.secondProperty 屬性值已從特定文件中在第二個方法中覆蓋。 這種方法允許我們在初始化上下文時定義不同的屬性值。
8. 結論
在本文中,我們重點介紹了在測試中如何覆蓋屬性的多種方法。我們還討論了何時使用每種解決方案,或者在某些情況下,如何混合使用它們。
當然,我們還有 <em @TestPropertySource</em> 註解可供使用。