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

Spring Boot中MockMvc测试JPA Repository遇异常的求助

解决测试中Collections.EMPTY_SET导致的UnsupportedOperationException问题

错误根源分析

你遇到的UnsupportedOperationException是因为Collections.EMPTY_SET是JDK提供的不可变空集合,它不支持任何修改操作(比如add()),调用这个方法自然会抛出异常,这是问题的核心。下面是分步修复方案:


1. 替换不可变集合为可变集合

把测试中创建角色集合的代码,从不可变的EMPTY_SET改成可变集合:

// 替换原来的错误代码
Set<Role> roles = new HashSet<>();
roles.add(optional.get());

如果只需要添加单个元素,也可以用更简洁的方式:

Set<Role> roles = Collections.singleton(optional.get());

2. 修正HTTP请求方法不匹配

你的Controller注册接口用的是@PostMapping("/signup"),但测试里误用了put()方法,这会导致405 Method Not Allowed错误。同时,Controller返回的是201 Created状态码,不是200 Ok,需要同步修改断言:

mockMvc.perform(post("/api/auth/signup")
        .contentType(MediaType.APPLICATION_JSON).content(json))
        .andExpect(status().isCreated()); // 对应Controller的created()返回值

3. 使用正确的请求体参数类型

你的Controller接收的是SignUpRequest对象,而非User对象,直接序列化User会导致字段不匹配。应该构造SignUpRequest实例来生成请求体:

SignUpRequest signUpRequest = new SignUpRequest();
signUpRequest.setName("testUserA");
signUpRequest.setUsername("testUserA");
signUpRequest.setEmail("testUserA@testing.com");
signUpRequest.setPassword("superSecretStuff");

Gson gson = new Gson();
String json = gson.toJson(signUpRequest);

4. 简化测试代码(可选优化)

测试中你创建的newTestUser对象其实不会被Controller用到——因为Controller会根据SignUpRequest重新构建User实例,所以这部分冗余代码可以删除,只保留mock逻辑和请求构造:

@Test
public void createUserTest() throws Exception {
    // Mock角色查询行为
    Role testRole = new Role();
    testRole.setName(RoleName.ROLE_USER);
    when(roleRepository.findByName(RoleName.ROLE_USER)).thenReturn(Optional.of(testRole));

    // 构造合法的注册请求
    SignUpRequest signUpRequest = new SignUpRequest();
    signUpRequest.setName("testUserA");
    signUpRequest.setUsername("testUserA");
    signUpRequest.setEmail("testUserA@testing.com");
    signUpRequest.setPassword("superSecretStuff");

    Gson gson = new Gson();
    String json = gson.toJson(signUpRequest);

    // 执行请求并断言结果
    mockMvc.perform(post("/api/auth/signup")
            .contentType(MediaType.APPLICATION_JSON)
            .content(json))
            .andExpect(status().isCreated())
            .andExpect(jsonPath("$.success").value(true))
            .andExpect(jsonPath("$.message").value("User registered successfully"));
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 04:37:07