Spring MockMVC GET测试报错500,请求排查问题及修复方法
让我帮你拆解下这个测试失败的问题,从报错日志和你的测试代码里能看出几个关键问题:
1. 请求路径不匹配(或控制器映射错误)
你在测试里调用的是get("/account/1"),但报错里的MockHttpServletRequest显示实际请求的URI是/users/1——这明显对不上啊!要么是你测试代码里写错了路径,应该请求/users/1而非/account/1;要么是你的控制器方法实际映射的是/users/{id},但测试里用了错误的路径。
2. 方法参数类型不匹配(500错误的核心原因)
报错里明确抛出了org.springframework.web.method.annotation.MethodArgumentTypeMismatchException,这个异常的意思是:控制器里处理请求的方法,它的路径参数(比如加了@PathVariable注解的参数)和你传入的1类型不匹配。举几个常见场景:
- 比如控制器方法参数是
Long id,但Spring没法把路径里的字符串"1"转成Long(不过一般Spring会自动做这个转换,除非你自定义了类型转换器出问题); - 或者路径变量的名称不匹配,比如控制器里写的是
@PathVariable("accountId") Long id,但路径却是/users/1,没有对应accountId的变量,导致参数绑定失败。
3. 视图名称断言不合理
你的测试里断言视图名称是/account/,这看起来不太对——通常视图名称不会以斜杠结尾的。而且如果控制器返回的是@ResponseBody格式的JSON数据,视图名称会是null,这时候你断言视图名称肯定会出问题;就算是返回模板视图,实际名称大概率是"account"或者"/account",而不是带尾斜杠的"/account/"。
一步步修复
第一步:修正请求路径
先把测试的请求路径和控制器的映射路径对齐。比如如果控制器方法映射的是/users/{id},那测试代码里要改成:
mockMvc.perform(get("/users/1"))
第二步:排查控制器参数绑定
检查你的控制器方法签名,确保路径参数能正确绑定:
- 确保
@PathVariable的参数类型和路径中的值兼容(比如Long、Integer都能接收数字字符串); - 确保路径变量名称和注解里的一致,比如:
如果参数名称和路径变量名一样,还可以省略注解里的名称:@GetMapping("/users/{id}") public String getAccount(@PathVariable("id") Long accountId) { // 业务逻辑 }@GetMapping("/users/{id}") public String getAccount(@PathVariable Long id) { // 业务逻辑 }
要是你用了自定义类型当参数,得确保Spring容器里注册了对应的类型转换器。
第三步:修正视图断言
如果控制器返回的是模板视图(比如Thymeleaf、JSP),先确认实际返回的视图名称是什么,再修改断言:
比如实际返回的是"account",就改成:
.andExpect(view().name("account"))
如果控制器返回的是JSON这类响应体,那就别断言视图了,换成断言响应体内容:
.andExpect(content().json("{\"id\":1,\"name\":\"测试账户\"}"))
修复后的完整测试示例
假设控制器映射的是/users/{id},返回视图"account",修复后的代码大概是这样:
@Test public void getAccount() throws Exception { mockMvc.perform(get("/users/1")) .andDo(print()) .andExpect(status().isOk()) .andExpect(view().name("account")); }
内容的提问来源于stack exchange,提问作者martine

