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 自定义属性源路径和属性值

我们也可以通过 locationsproperties 属性来自定义属性源的位置或直接指定属性值:

@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 会继承父类中定义的 locationsproperties。我们可以通过以下两个属性来控制这一行为:

  • inheritLocations
  • inheritProperties

它们默认值都是 true,可根据需要设置为 false

4. 总结

通过上面的示例,我们了解了如何有效地使用 @TestPropertySource 注解来覆盖测试中的配置属性。

更多实际场景的示例可以参考 GitHub 仓库


原始标题:A Quick Guide to @TestPropertySource | Baeldung