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

JUnit测试中如何通过@WithMockUser方式模拟密码错误的用户?

@WithMockUser 无法覆盖密码错误/用户不存在的测试场景

使用@WithMockUser时,底层会调用WithMockUserSecurityContextFactory#createSecurityContext方法生成包含模拟用户的安全上下文,但这种方式生成的认证对象始终处于已认证状态,完全跳过了密码验证逻辑,因此无法测试密码错误、用户不存在这类需要完整认证流程的场景。

相关代码实现

SecurityConfiguration 类

@Bean
public InMemoryUserDetailsManager userDetailsService(PasswordEncoder passwordEncoder) {

    String encPW = passwordEncoder.encode("123456");
    log.debug(encPW);
    UserDetails user = User.withUsername("user")
            .password(encPW)
            //.password("123456")
            .roles("USER")
            .build();

    UserDetails admin = User.withUsername("admin")
            .password(passwordEncoder.encode("123456"))
            .roles("USER", "ADMIN")
            .build();

    return new InMemoryUserDetailsManager(user, admin);
}

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http
            .csrf((csrf)
                    -> csrf.ignoringRequestMatchers("/demo/**"))
            .authorizeHttpRequests((ah)
                    -> ah
                    .requestMatchers("/demo/authenticate").authenticated()
                    .anyRequest().permitAll()
            )
            .httpBasic(Customizer.withDefaults())
            ;
    return http.build();
}

测试代码

//@WithMockUser(username = "no_exist_user", password = "123456777") // 此注解无效,会直接跳过认证流程
@Test
void testHelloByWrongPw() throws Exception {

    mvc.perform(
                    post("/demo/authenticate")
                            .with(httpBasic("no_exist_user", "123456777"))
                            .content("{\"a1\":\"123\"}")
                            .contentType(MediaType.APPLICATION_JSON)
                            .accept(MediaType.APPLICATION_JSON)
                            .queryParam("a1","123")
            )
            .andExpect(status().isUnauthorized());
}

关键说明

@WithMockUser本质是直接在安全上下文中植入一个已认证的用户,不会触发Spring Security的完整认证流程(包括密码校验、用户信息查询)。如果要测试密码错误、用户不存在这类场景,必须使用httpBasic()模拟真实的HTTP Basic认证请求,这样才能让系统走完整的认证逻辑,返回预期的401 Unauthorized状态码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 13:17:24