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

Spring Boot测试问题:@TestPropertySource未覆盖@EnableAutoConfiguration

Spring Boot测试:@TestPropertySource未能覆盖@EnableAutoConfiguration的LDAP配置

我正在使用Spring Data LDAP从LDAP服务器获取用户数据,项目的文件结构如下:

main
  java
    com.test.ldap
      Application.java
      Person.java
      PersonRepository.java
  resources
    application.yml
    schema.ldif
test
  java
    Tests.java
  resources
    test.yml
    test_schema.ldif

测试类代码(部分内容截断):

import com.test.ldap.Person;
import com.test.ldap.PersonRepository;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework...

遇到的问题

在Spring Boot测试中,使用@TestPropertySource无法覆盖@EnableAutoConfiguration加载的LDAP配置,测试仍然使用了主资源下的application.yml配置,而非测试资源的test.yml。


解决方案与排查要点

1. 注意:@TestPropertySource默认不支持YAML文件

这是最容易踩的坑!Spring的@TestPropertySource默认仅支持.properties格式的配置文件,如果你用的是.yml,需要自定义PropertySourceFactory来解析YAML内容。

首先创建一个YAML解析的工厂类:

import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
import org.springframework.core.env.PropertiesPropertySource;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.support.EncodedResource;
import org.springframework.core.io.support.PropertySourceFactory;

import java.io.IOException;
import java.util.Properties;

public class YamlPropertySourceFactory implements PropertySourceFactory {
    @Override
    public PropertySource<?> createPropertySource(String name, EncodedResource resource) throws IOException {
        YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
        factory.setResources(resource.getResource());
        Properties properties = factory.getObject();
        return new PropertiesPropertySource(
            name != null ? name : resource.getResource().getFilename(), 
            properties
        );
    }
}

然后在测试类上指定这个工厂来加载YAML配置:

@RunWith(SpringRunner.class)
@SpringBootTest
@TestPropertySource(
    locations = "classpath:test.yml", 
    factory = YamlPropertySourceFactory.class
)
public class Tests {

    @Autowired
    private PersonRepository personRepository;

    @Test
    public void testLdapRetrieval() {
        // 你的测试逻辑
        Person testPerson = personRepository.findByUid("test-user");
        // 断言验证
    }
}

2. 直接用@SpringBootTest的properties属性覆盖配置

如果不想处理YAML的解析问题,更简单的方式是直接在@SpringBootTest中指定要覆盖的属性,这种方式的优先级高于任何配置文件:

@RunWith(SpringRunner.class)
@SpringBootTest(properties = {
    "spring.ldap.urls=ldap://localhost:3389", // 测试LDAP地址
    "spring.ldap.base=dc=test,dc=local",
    "spring.ldap.username=cn=test-admin,dc=test,dc=local",
    "spring.ldap.password=test-pass"
})
public class Tests {
    // ...测试代码
}

3. 确认配置文件路径与加载顺序

  • 确保测试配置文件test.yml放在src/test/resources下,使用classpath:test.yml作为路径,不要写错路径。
  • Spring Boot的属性优先级中,@TestPropertySource的配置优先级高于主资源的application.yml,但如果有其他配置源(比如系统属性、环境变量)可能会干扰,测试环境下尽量避免这类外部配置。

4. 确保测试类加载正确的Spring上下文

如果你的测试类没有使用@SpringBootTest,需要用@ContextConfiguration配合@EnableAutoConfiguration来加载上下文,同时指定@TestPropertySource:

@RunWith(SpringRunner.class)
@ContextConfiguration(classes = Application.class)
@TestPropertySource(
    locations = "classpath:test.yml", 
    factory = YamlPropertySourceFactory.class
)
public class Tests {
    // ...
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:48:39