如何用MockMVC测试无@RequestBody/@RequestParam的FormData接口
解决MockMVC测试无注解参数绑定的Candidato对象为null问题
这种情况我之前也碰到过——没法用@RequestBody或@RequestParam注解自动绑定参数,得手动从请求里解析数据,这时候MockMVC测试就得对应模拟请求的输入方式才能让控制器正确拿到数据。我给你分几种常见场景说具体解法:
场景1:控制器手动读取请求体JSON解析Candidato
如果你的控制器是通过HttpServletRequest的输入流读取JSON,再手动反序列化为Candidato对象,比如:
@PostMapping("/candidatos") public ResponseEntity<?> saveCandidato(HttpServletRequest request) throws IOException { ObjectMapper mapper = new ObjectMapper(); Candidato candidato = mapper.readValue(request.getInputStream(), Candidato.class); // 业务逻辑处理 return ResponseEntity.ok(candidato); }
那测试时需要用MockMVC发送带JSON体的POST请求,并设置正确的Content-Type:
@Test void testSaveCandidato() throws Exception { // 构建测试用的Candidato对象 Candidato testCandidato = new Candidato(); testCandidato.setNome("Carlos Silva"); testCandidato.setEmail("carlos@example.com"); testCandidato.setCargo("Desenvolvedor"); // 把对象序列化为JSON字符串 ObjectMapper objectMapper = new ObjectMapper(); String jsonBody = objectMapper.writeValueAsString(testCandidato); // 模拟请求并验证结果 mockMvc.perform(post("/candidatos") .contentType(MediaType.APPLICATION_JSON) // 必须指定JSON类型 .content(jsonBody)) // 传入JSON请求体 .andExpect(status().isOk()) .andExpect(jsonPath("$.nome").value("Carlos Silva")); // 验证返回的对象属性正确 }
场景2:控制器手动从请求参数提取属性
如果你的控制器是通过request.getParameter()逐个提取属性组装Candidato,比如:
@PostMapping("/candidatos") public ResponseEntity<?> saveCandidato(HttpServletRequest request) { Candidato candidato = new Candidato(); candidato.setNome(request.getParameter("nome")); candidato.setEmail(request.getParameter("email")); candidato.setCargo(request.getParameter("cargo")); // 业务逻辑处理 return ResponseEntity.ok(candidato); }
测试时需要用MockMVC的param()方法逐个设置请求参数:
@Test void testSaveCandidato() throws Exception { mockMvc.perform(post("/candidatos") .param("nome", "Carlos Silva") .param("email", "carlos@example.com") .param("cargo", "Desenvolvedor")) .andExpect(status().isOk()) .andExpect(jsonPath("$.email").value("carlos@example.com")); }
如果是表单提交的场景,记得加上.contentType(MediaType.APPLICATION_FORM_URLENCODED),不过MockMVC默认会处理表单参数,不加也能正常工作。
关键注意事项
- 确保Candidato类的可访问性:要有公开的无参构造方法,以及对应的
getter/setter,或者用Java 16+的record类(自动生成这些方法),否则Jackson或手动解析时无法正确实例化对象。 - 排查请求传递是否正常:可以在控制器里加日志,打印读取到的请求体或参数,确认是MockMVC请求没传对,还是控制器的解析逻辑有问题。
- 如果是GET请求:把
post()换成get(),param()方法依然适用,因为GET参数是拼接在URL上的。
内容的提问来源于stack exchange,提问作者jaxonjma
相关产品推荐
相关产品推荐

