使用JsonPath进行JUnit测试报错:$.first_name路径无值求助
问题:REST控制器单元测试中JsonPath断言失败
对REST控制器的addUser()方法进行单元测试时,不使用JsonPath断言测试可正常执行,但使用JsonPath对JSON响应的$.first_name字段做断言时,出现错误:No value at JSON path "$.first_name",底层错误提示json can not be null or empty。
问题根源及解决方法
1. Mock参数匹配失败导致响应body为null
测试中原本使用Mockito.when(userService.addUser(user)).thenReturn(user);,这里的参数是测试代码中创建的具体User实例,但Spring MVC处理请求时会将传入的JSON反序列化为一个全新的User实例,两个实例不是同一个对象,导致Mockito的匹配条件不满足,userService.addUser()返回null,最终控制器响应的body为空,JsonPath自然找不到对应字段。
修复方式:使用Mockito的参数匹配器any(User.class)来匹配任意User类型的参数,确保Mock能正确返回预期的User对象:
Mockito.when(userService.addUser(any(User.class))).thenReturn(user);
2. 确认Jackson序列化配置生效
实体类中已经通过@JsonProperty("first_name")指定了JSON字段名,测试中注入的ObjectMapper是Spring Boot自动配置的实例,已包含Jackson的序列化规则,无需额外调整。
3. 验证响应内容(可选)
可以通过andDo(print())打印完整的请求和响应信息,确认响应body是否为预期的JSON内容,帮助快速定位问题。
修改后的完整测试类代码
@WebMvcTest(UserRestApiController.class) public class UserRestApiControllerTest { private static final String END_POINT_PATH = "/api/v1/users"; @MockBean private UserServiceImpl userService; @Autowired MockMvc mockMvc; @Autowired ObjectMapper objectMapper; @Test public void testAddUserShouldReturn201Created() throws Exception { User user = new User(); user.setFirstName("James"); user.setLastName("Kwarteng"); user.setEmail("james@gmail.com"); user.setPassword("23464433"); user.setPhoneNumber("04233455"); // 使用参数匹配器匹配任意User实例,确保Mock逻辑生效 Mockito.when(userService.addUser(any(User.class))).thenReturn(user); String bodyContent = objectMapper.writeValueAsString(user); mockMvc.perform(post(END_POINT_PATH).contentType("application/json").content(bodyContent)) .andExpect(status().isCreated()) .andExpect(jsonPath("$.first_name", is("James"))) .andDo(print()); } }
内容的提问来源于stack exchange,提问作者Solomon Otoo
相关产品推荐
相关产品推荐

