Spring Boot REST服务集成测试空指针异常,配置属性未加载
问题根源及解决方案
核心问题:MockBean替换了真实配置类
你的测试类中使用了@MockBean CategoryConfiguration,这会把Spring容器中原本的CategoryConfiguration实例替换成Mock对象,导致真实的配置加载逻辑完全不执行,自然CategoryConfigurationProperties无法被正确初始化,getValuesFromProperties()返回null。
具体修复步骤
1. 移除不必要的MockBean和重复配置
- 删除测试类中的
@MockBean CategoryConfiguration,保留真实的配置类实例,让Spring正常加载配置。 - 移除
@ContextConfiguration(classes = CategoryConfiguration.class),因为@SpringBootTest(classes = {MyApplication.class})已经会加载整个应用上下文,包含所有配置类,重复指定会导致上下文加载异常。
2. 修正CategoryConfigurationProperties的注解
@ConfigurationProperties默认通过setter方法绑定属性,你当前用了@AllArgsConstructor且无无参构造,Spring可能无法正确实例化这个配置类。可二选一修改:
方案一:添加无参构造+Setter
@ConfigurationProperties(prefix = "my-config") @Getter @Setter @NoArgsConstructor // 添加无参构造 public class CategoryConfigurationProperties { private Map<String,Map<String,List<String>>> valuesFromProperties; }
方案二:用构造绑定(Spring Boot 2.2+支持)
@ConfigurationProperties(prefix = "my-config") @Getter @AllArgsConstructor @ConstructorBinding // 告诉Spring用构造方法绑定属性 public class CategoryConfigurationProperties { private Map<String,Map<String,List<String>>> valuesFromProperties; }
3. 确保测试环境配置文件正确加载
@TestPropertySource的properties参数用于设置单个属性,指定配置文件路径要改用locations参数:
@TestPropertySource(locations = {"classpath:application-category.yml", "classpath:application.properties"})
- 确认
application-category.yml放在src/test/resources目录下,保证测试时能被classpath加载。
4. 验证配置加载是否生效
可在测试类中注入配置类,打印值确认:
@Autowired private CategoryConfigurationProperties configProps; @BeforeEach public void setup() { System.out.println("Loaded config: " + configProps.getValuesFromProperties()); }
修复后的测试类示例
@ExtendWith(SpringExtension.class) @SpringBootTest(classes = {MyApplication.class}, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @ActiveProfiles("test") @AutoConfigureMockMvc @TestPropertySource(locations = {"classpath:application-category.yml", "classpath:application.properties"}) class MyControllerIntegrationTest { @Autowired private MockMvc mockMvc; @Autowired private CategoryConfigurationProperties configProps; @BeforeEach public void setup() { // 可选:验证配置是否加载 System.out.println("Loaded config: " + configProps.getValuesFromProperties()); } @Test void testCreateProduct() throws Exception { MvcResult result = mockMvc.perform(post("/your-endpoint") .contentType(MediaType.APPLICATION_JSON) .content("your-request-body")); // 断言逻辑 assert result.getResponse().getStatus() == HttpStatus.OK.value(); } }
额外检查点
- 确认
application-category.yml中的配置前缀与CategoryConfigurationProperties的prefix一致,示例格式:
my-config: valuesFromProperties: product1: category1: - "value1" - "value2"
内容的提问来源于stack exchange,提问作者Andulos
相关产品推荐
相关产品推荐

