Spring Boot API测试中使用JsonPath获取响应体错误消息失败的问题排查
我看你在测试自己开发的Spring Boot API时遇到了麻烦:明明响应里包含"message": "Name does not exist"字段,但用jsonPath("$.message")断言时却抛出了No value at JSON path "$.message"的错误。结合你的代码和响应示例,我整理了几个可能的原因和对应的解决办法:
1. 路径变量的空格未编码,触发默认404而非自定义响应
你的测试请求路径里包含空格:"/Non existent name",URL中的空格需要被编码为%20,否则MockMvc可能无法正确匹配到你的控制器方法,反而触发了Spring Boot默认的404错误(这种默认响应的结构可能和你自定义的不一样,甚至没有message字段)。
解决办法:对包含空格的路径变量进行URL编码:
import java.net.URLEncoder; import java.nio.charset.StandardCharsets; @Test void whenNonExistingNamePassedInThenReturn404() throws Exception { String nonExistingName = "Non existent name"; // 编码路径变量中的空格 String encodedName = URLEncoder.encode(nonExistingName, StandardCharsets.UTF_8); mockMvc.perform(get(BASE_URL + END_POINT + "/" + encodedName) .contentType(MediaType.APPLICATION_JSON) .accept(MediaType.APPLICATION_JSON)) // 明确要求返回JSON格式 .andExpect(status().isNotFound()) // 直接断言404,比is4xx更精确 .andDo(print()) // 打印完整响应,方便调试时确认返回结构 .andExpect(jsonPath("$.message", Matchers.is(NAME_NOT_FOUND))); }
2. 未指定Accept头,服务器返回非JSON格式响应
你设置了contentType(MediaType.APPLICATION_JSON),但这个是告诉服务器你发送的请求体格式;如果没有设置accept(MediaType.APPLICATION_JSON),服务器可能会返回HTML格式的错误页面,而非你预期的JSON结构,自然找不到$.message字段。
上面的代码已经加上了.accept(MediaType.APPLICATION_JSON),确保服务器返回JSON响应。
3. 调试技巧:打印完整响应确认结构
如果还是有问题,一定要用.andDo(print())打印出完整的请求和响应内容,这样你就能看到MockMvc实际收到的响应是什么样的——比如是不是真的返回了你预期的JSON结构,还是有其他嵌套或者字段名不一致的情况。
额外检查:确认依赖和导入是否正确
确保你导入的是正确的jsonPath和Matchers类:
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.hamcrest.Matchers.is;
如果导入了错误的匹配器类,也可能导致断言失败。
内容的提问来源于stack exchange,提问作者meniman98

