1. 概述
Spring 提供了丰富的功能来支持测试代码。在某些情况下,我们需要通过特定的配置属性来模拟测试场景。
这时就可以使用 @TestPropertySource
注解。这个注解允许我们定义具有最高优先级的配置属性源,从而覆盖项目中其他地方定义的属性。
本文将通过几个示例来演示如何使用 @TestPropertySource
,并分析它的默认行为以及主要属性。
如果你对 Spring Boot 的测试还不太熟悉,可以先看看这篇 《Spring Boot 测试指南》。
2. 依赖配置
最简单的做法是,在 pom.xml
文件中添加 spring-boot-starter-test
依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
你可以前往 Maven Central 确认是否使用的是最新版本。
3. 如何使用 @TestPropertySource
假设我们有一个类通过 @Value
注解注入了一个属性值:
@Component
public class ClassUsingProperty {
@Value("${baeldung.testpropertysource.one}")
private String propertyOne;
public String retrievePropertyOne() {
return propertyOne;
}
}
我们可以通过 @TestPropertySource
注解来定义一个新的属性源,覆盖这个属性的值:
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = ClassUsingProperty.class)
@TestPropertySource
public class DefaultTest {
@Autowired
ClassUsingProperty classUsingProperty;
@Test
public void givenDefaultTPS_whenVariableRetrieved_thenDefaultFileReturned() {
String output = classUsingProperty.retrievePropertyOne();
assertThat(output).isEqualTo("default-value");
}
}
✅ 通常,使用 @TestPropertySource
时会配合 @ContextConfiguration
一起使用,用于加载和配置测试所需的 ApplicationContext
。
⚠️ 默认情况下,@TestPropertySource
会尝试加载与当前测试类同名的 .properties
文件,该文件路径基于当前类所在的包。
例如,如果测试类在 com.baeldung.testpropertysource
包下,那么就需要在 classpath 中提供以下文件:
# DefaultTest.properties
baeldung.testpropertysource.one=default-value
我们只需将这个文件放到 resources
目录下即可。
3.1 自定义属性源路径和属性值
我们也可以通过 locations
和 properties
属性来自定义属性源的位置或直接指定属性值:
@TestPropertySource(locations = "/other-location.properties",
properties = "baeldung.testpropertysource.one=other-property-value")
✅ 如果要定义多个属性,可以使用数组形式:
@TestPropertySource(
locations = "/other-location.properties",
properties = {
"baeldung.testpropertysource.one=one",
"baeldung.testpropertysource.two=two"
})
public class MultiplePropertiesInPropertySourceIntegrationTest {
3.2 使用 Java 15+ 文本块(Text Block)
从 Java 15 和 Spring 6.1.0 开始,我们可以使用 多行文本块 来定义多个属性,代码更清晰:
@TestPropertySource(
locations = "/other-location.properties",
properties = """
baeldung.testpropertysource.one=one
baeldung.testpropertysource.two=two
""")
public class MultiplePropertiesInPropertySourceTextBlockIntegrationTest {
3.3 继承父类的属性配置
默认情况下,@TestPropertySource
会继承父类中定义的 locations
和 properties
。我们可以通过以下两个属性来控制这一行为:
inheritLocations
inheritProperties
它们默认值都是 true
,可根据需要设置为 false
。
4. 总结
通过上面的示例,我们了解了如何有效地使用 @TestPropertySource
注解来覆盖测试中的配置属性。
更多实际场景的示例可以参考 GitHub 仓库。