Spring Boot读取YAML中Map时测试抛空指针异常,求助
问题排查:Spring配置类Map注入空指针异常
问题场景
YAML配置:
replacement: ID: 0000000016: 9000000011 0000000013: 8000000014 0000000002: 9000000000
配置类代码:
@Configuration @NoArgsConstructor @AllArgsConstructor @ConfigurationProperties(prefix = "replacement") @Getter @Setter public class SourceConfig { private Map<String, String> ID = new HashMap<>(); }
测试类代码:
@ExtendWith(SpringExtension.class) @EnableConfigurationProperties(value = SourceConfig.class) @TestPropertySource("classpath:yaml file name") class SourceConfigTest { @Autowired private SourceConfig sourceconfig; @Test void getID() { assertThat(sourceconfig).isNotNull(); assertTrue(sourceconfig.getID().containsKey("0000000016")); } }
运行测试时,sourceconfig.getID()抛出空指针异常,无法正常获取Map配置。
解决方案
1. 修正@TestPropertySource的YAML文件加载方式
@TestPropertySource默认仅支持.properties文件,直接指定YAML文件会导致配置无法加载。需要自定义YamlPropertySourceFactory来解析YAML:
- 创建工厂类:
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); } }
- 修改测试类注解:
@TestPropertySource(value = "classpath:your-actual-file.yaml", factory = YamlPropertySourceFactory.class)
注意替换your-actual-file.yaml为实际的YAML文件名
2. 移除干扰的@AllArgsConstructor注解
配置类中同时存在@NoArgsConstructor和@AllArgsConstructor,Spring实例化时会优先使用全参构造函数,此时ID字段会被传入null(配置绑定在构造之后执行),覆盖了原本的new HashMap<>()初始化。移除@AllArgsConstructor即可:
@Configuration @NoArgsConstructor @ConfigurationProperties(prefix = "replacement") @Getter @Setter public class SourceConfig { private Map<String, String> ID = new HashMap<>(); }
3. 验证配置绑定的字段匹配
Spring配置绑定默认对大小写敏感,确保YAML中的ID和配置类中的ID字段名称完全一致。若需要宽松匹配,可添加参数:
@ConfigurationProperties(prefix = "replacement", ignoreInvalidFields = true, ignoreUnknownFields = true)
4. 替换测试类注解(可选)
如果是Spring Boot项目,直接使用@SpringBootTest替代原有注解,它会自动加载默认配置:
@SpringBootTest @TestPropertySource(value = "classpath:your-actual-file.yaml", factory = YamlPropertySourceFactory.class) class SourceConfigTest { // 测试代码不变 }
验证测试
修改后重新运行测试,sourceconfig.getID()可正常获取配置中的Map,断言containsKey("0000000016")会成立。
内容的提问来源于stack exchange,提问作者akshay ithape
相关产品推荐
相关产品推荐

