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
相关产品推荐
相关产品推荐

