单元测试中加载自定义YAML配置的关键是手动构建Spring环境并注册YamlPropertiesFactoryBean或自定义PropertySourceFactory,而非启动完整Spring Boot应用;推荐使用YamlPropertiesFactoryBean,需引入snakeyaml依赖,通过ClassPathResource加载YAML并注入Environment验证属性值。

在单元测试中加载自定义 YAML 配置,关键不是启动完整 Spring Boot 应用,而是手动构建可加载 YAML 的 Spring 环境,并确保 YamlPropertiesFactoryBean 或自定义 PropertySourceFactory 能被正确注册和触发。纯 JUnit 测试(无 @SpringBootTest)也能做到,但需补全依赖和初始化逻辑。
✅ 使用 YamlPropertiesFactoryBean(推荐,轻量、稳定)
适用于 Spring Framework 项目或 Spring Boot 单元测试,不依赖自动配置。
步骤:
-
引入 SnakeYAML(Maven):
立即学习“Java免费学习笔记(深入)”;
<dependency> <groupId>org.yaml</groupId> <artifactId>snakeyaml</artifactId> <scope>test</scope> </dependency> -
在测试类中手动加载 YAML 并注入
Environment:@Test void testYamlConfigLoaded() { // 1. 创建独立的 ApplicationContext(非 Web,轻量) AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); // 2. 手动加载 YAML 配置 YamlPropertiesFactoryBean yamlFactory = new YamlPropertiesFactoryBean(); yamlFactory.setResources(new ClassPathResource("test-config.yml")); // 放在 src/test/resources/ Properties props = yamlFactory.getObject(); // 已扁平化,如 "server.port"="8080" // 3. 注册为 PropertySource 到 Environment ConfigurableEnvironment env = ctx.getEnvironment(); env.getPropertySources().addFirst(new PropertiesPropertySource("test-yaml", props)); // 4. 验证读取 assertThat(env.getProperty("database.url")).isEqualTo("jdbc:h2:mem:test"); assertThat(env.getProperty("app.name")).isEqualTo("demo-app"); }
⚠️ 注意:
YamlPropertiesFactoryBean会自动将嵌套结构(如server: { port: 8080 })转为点号路径(server.port),无需自己 flatten。
JavaStoryDevelop下载你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
✅ 使用 @TestConfiguration + @PropertySource(需自定义 PropertySourceFactory)
适合想复用生产环境 @PropertySource 方式做测试的场景。
前提:
- 已实现
YamlPropertySourceFactory(参考知识库中递归 flatten 示例) - 测试类启用
@ContextConfiguration
@TestConfiguration
static class TestConfig {
@Bean
public static PropertySourcesPlaceholderConfigurer configurer() {
PropertySourcesPlaceholderConfigurer c = new PropertySourcesPlaceholderConfigurer();
c.setIgnoreUnresolvablePlaceholders(true);
return c;
}
}
@SpringBootTest
@ContextConfiguration(classes = {TestConfig.class})
@PropertySource(
value = "classpath:test-config.yml",
factory = YamlPropertySourceFactory.class // 你自己的实现
)
class YamlLoadTest {
@Autowired
private Environment env;
@Test
void shouldReadYamlViaPropertySource() {
assertEquals("jdbc:h2:mem:test", env.getProperty("database.url"));
assertEquals(8080, Integer.parseInt(env.getProperty("server.port")));
}
}✅ 此方式更贴近真实运行时行为,但必须确保
YamlPropertySourceFactory类在 classpath 且无依赖缺失(如Yaml类来自 snakeyaml)。
✅ 直接用 SnakeYAML 解析(脱离 Spring,最简单)
如果只是校验 YAML 内容或做数据驱动测试,不需要 Spring 环境:
@Test
void testRawYamlParse() {
Yaml yaml = new Yaml();
InputStream is = getClass().getResourceAsStream("/test-config.yml");
Map<String, Object> data = yaml.load(is);
String url = (String) ((Map) ((Map) data.get("database")).get("url"));
assertEquals("jdbc:h2:mem:test", url);
}? 适合参数化测试(如
@ParameterizedTest+@ValueSource)、配置格式校验、生成测试用例等场景。
不复杂但容易忽略:
- YAML 文件必须放在
src/test/resources/下才能被ClassPathResource正确定位; -
YamlPropertiesFactoryBean不支持@PropertySource直接使用(它不是PropertySourceFactory),必须走Properties中转; - 若用
@ConfigurationProperties绑定,记得在测试类上加@EnableConfigurationProperties(TestConfig.class)。


















