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

SpringBoot3中@EnableMethodSecurity导致@WebMvcTest的@Value解析失败

问题分析与解决方案

问题描述

在SpringBoot 3 + JVM 17的微服务中,通过Spring Security的@EnableMethodSecurity实现@PreAuthorize权限控制,但使用@WebMvcTest编写控制器单元测试时,出现@Value解析失败的报错:

Caused by: org.springframework.beans.TypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'boolean'; Invalid boolean value [${myFeature.active:true}]

移除配置类中的@EnableMethodSecurity注解后,测试可正常运行。

原因

启用@EnableMethodSecurity时,Spring Security会引入更多自动配置组件,部分组件需要解析配置属性。但@WebMvcTest默认仅加载Web层相关配置,未完整加载环境配置的解析逻辑(如PropertySourcesPlaceholderConfigurer),导致@Value中的占位符未被正确解析,直接将${myFeature.active:true}作为字符串传入,无法转换为boolean类型。

解决方案

方案1:添加占位符解析器Bean

在测试类中添加静态配置类,手动注册PropertySourcesPlaceholderConfigurer,确保占位符被正确解析:

@WebMvcTest(controllers = DocApiController.class)
class DocApiControllerTest {
    @Autowired
    protected MockMvc mockMvc;
    @MockBean
    private DocService service;

    @TestConfiguration
    static class TestConfig {
        @Bean
        public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
            return new PropertySourcesPlaceholderConfigurer();
        }
    }

    @Test
    void test_getDocuments_success() throws Exception {
        Result response = new Result();
        when(service.search(any())).thenReturn(response);
        mockMvc.perform(get("/document/get?pageSize=10&pageNumber=1"))
                .andExpect(status().isOk());
    }
}

方案2:直接指定测试属性

在测试类上通过@TestPropertySource直接配置属性值,跳过占位符解析:

@WebMvcTest(controllers = DocApiController.class)
@TestPropertySource(properties = {"myFeature.active=true"})
class DocApiControllerTest {
    @Autowired
    protected MockMvc mockMvc;
    @MockBean
    private DocService service;

    @Test
    void test_getDocuments_success() throws Exception {
        Result response = new Result();
        when(service.search(any())).thenReturn(response);
        mockMvc.perform(get("/document/get?pageSize=10&pageNumber=1"))
                .andExpect(status().isOk());
    }
}

方案3:引入必要的配置类

如果需要加载Security配置类,可在@WebMvcTest中指定包含该配置类,确保环境配置逻辑被加载:

@WebMvcTest(
    controllers = DocApiController.class,
    includeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = config.class)
)
class DocApiControllerTest {
    @Autowired
    protected MockMvc mockMvc;
    @MockBean
    private DocService service;

    @Test
    void test_getDocuments_success() throws Exception {
        Result response = new Result();
        when(service.search(any())).thenReturn(response);
        mockMvc.perform(get("/document/get?pageSize=10&pageNumber=1"))
                .andExpect(status().isOk());
    }
}

注:此方式会引入更多Security相关Bean,需确保这些Bean的依赖已被Mock或提供。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 05:13:14