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

WebMvcTest测试疑问:从WebSecurityConfigurerAdapter迁移至SecurityFilterChain后@WithMockUser测试失效

问题原因与解决方案

这个问题其实很常见——当你切换到Spring Security的组件式配置(SecurityFilterChain + UserDetailsManager Bean)后,@WebMvcTest 默认不会自动加载这些安全相关的Bean,导致@WithMockUser无法生效,最终返回401未授权。

为什么旧配置能正常工作?

旧的WebSecurityConfigurerAdapter配置类上标注了@EnableWebSecurity,这个注解会触发Spring Security的自动配置逻辑,而@WebMvcTest在默认情况下会扫描并加载带有@EnableWebSecurity的配置类,所以你的测试能拿到正确的安全上下文,@WithMockUser也就正常生效了。

而新的组件式配置只是单独定义了SecurityFilterChain和InMemoryUserDetailsManager Bean,没有触发自动配置的注解,@WebMvcTest作为一个专注于MVC层的测试切片,默认不会加载用户自定义的这些Bean,所以测试上下文里没有安全过滤链,@WithMockUser的模拟用户信息也无法被识别,自然就返回401了。

修复方案

最简单的解决办法就是在你的@WebMvcTest测试类里显式导入安全配置类,让测试上下文加载必要的安全Bean:

@WebMvcTest(TestController.class)
@Import(SecurityConfiguration.class) // 加上这一行
class TestControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @Test
    @WithMockUser(username = "user", roles = {"USER"})
    void givenMockedCredentials_shouldAccessSecuredEndpoint() throws Exception {
        mockMvc.perform(get("/secured"))
                .andExpect(status().isOk())
                .andExpect(content().string("Hello secured world!"));
    }

    // 其他测试方法...
}

这样修改后,测试会加载你的SecurityConfiguration类中的SecurityFilterChain和InMemoryUserDetailsManager Bean,@WithMockUser就能正确模拟授权用户,测试也就会返回200状态码了。

另外,如果你不想导入整个配置类,也可以单独定义测试专用的安全配置Bean,然后通过@Import导入,但对于大部分场景来说,直接导入生产用的安全配置是最直接的方式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 01:37:41