You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Spring测试中用@TestPropertySource解析属性占位符?

问题根源与解决方案

你的问题出在两个关键误用:

1. @TestPropertySource注解的位置错误

@TestPropertySource是测试类专属注解,只能用在测试类上,不能放在@Configuration配置类中。你之前把它写在配置类里,Spring Test框架根本不会处理这个注解,导致配置的属性完全无法加载到上下文。

2. 手动导入PropertySourcesPlaceholderConfigurer干扰自动配置

Spring Boot已经自动配置了适配测试环境的占位符解析器,手动导入PropertySourcesPlaceholderConfigurer会覆盖这个自动配置的实例。而自定义的解析器初始化时机早于Spring Test加载测试属性源的时机,自然无法读取@TestPropertySource中的配置。


修改后的正确代码

测试类调整

将@TestPropertySource移到测试类上,移除配置类中多余的@Import和@TestPropertySource:

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit.jupiter.SpringExtension;

import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;

@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = ServerPropertiesTest.ServerPropertiesTestConfig.class)
@TestPropertySource(properties = "server.port=8080") // 移到测试类上
class ServerPropertiesTest {
    @Autowired
    GatewayMeta gatewayMeta;

    @Test
    void ifNoServerSpecified_serversHasOneServerMatchingLocalhostServerPort() {
        List<String> servers = gatewayMeta.getServers();
        assertThat(servers).hasSize(1);
        String server = servers.get(0);
        assertThat(server).isEqualTo("http://localhost:8080");
    }

    @Configuration
    @EnableConfigurationProperties(GatewayMeta.class)
    // 移除@Import和@TestPropertySource
    static class ServerPropertiesTestConfig {
    }
}

属性覆盖场景测试

如果需要用@TestPropertySource覆盖application-test.properties中的配置,只需保持@TestPropertySource在测试类上即可,它的优先级高于@PropertySource,会自动覆盖对应属性:

// 测试类上的配置会覆盖application-test.properties中的server.port
@TestPropertySource(properties = "server.port=8000")

更简洁的Spring Boot测试写法

如果是Spring Boot项目,推荐用@SpringBootTest替代手动配置上下文,它会自动加载所有Spring Boot自动配置,代码更简洁:

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;

import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;

@SpringBootTest(classes = GatewayMeta.class)
@TestPropertySource(properties = "server.port=8000")
class ServerPropertiesTest {
    @Autowired
    GatewayMeta gatewayMeta;

    @Test
    void ifNoServerSpecified_serversHasOneServerMatchingLocalhostServerPort() {
        List<String> servers = gatewayMeta.getServers();
        assertThat(servers).containsExactly("http://localhost:8000");
    }
}

内容的提问来源于stack exchange,提问作者Powet

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 02:43:22