You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JUnit测试Post接口报错:JSON路径$.id无值问题排查

排查JUnit测试中JSON路径$.id无值的问题

问题背景

编写Post方法控制器的JUnit测试时,出现错误:java.lang.AssertionError: No value at JSON path "$.id",附带完整错误栈信息,以下是相关代码片段及错误详情。

测试代码

@Test
public void testCreateCar() throws Exception {

  String custJson = "{\"name\": \"John Doe\", " +
                    "\"street\": \"123 Main St\", " +
                    "\"house_No\": \"45B\", " +
                    "\"place\": \"Springfield\", " +
                    "\"email\": \"john.doe@example.com\", " +
                    "\"ph_Number\": \"1234567890\"}";
  
  
CustomerEntity customer = new CustomerEntity();
customer.setters except ID...


CustomerEntity customer2 = new CustomerEntity();
customer2.setters.....

given(custService.createCust(customer)).willReturn(customer2);
mvc.perform(MockMvcRequestBuilders.post("/api/createCust")
    .contentType(MediaType.APPLICATION_JSON).content(custJson))
    .andExpect(MockMvcResultMatchers.status().isOk())
    .andExpect(MockMvcResultMatchers.jsonPath("$.id").value(1))
    .andExpect(MockMvcResultMatchers.jsonPath("$.name").value("John Doe"))
    .andExpect(MockMvcResultMatchers.jsonPath("$.street").value("123 Main St"))
    .andExpect(MockMvcResultMatchers.jsonPath("$.house_No").value("45B"))
    .andExpect(MockMvcResultMatchers.jsonPath("$.place").value("Springfield"))
    .andExpect(MockMvcResultMatchers.jsonPath("$.email").value("john.doe@example.com"))
    .andExpect(MockMvcResultMatchers.jsonPath("$.ph_Number").value("1234567890"));
}

CustomerEntity实体类

@Entity
public class CustomerEntity {

public CustomerEntity(Integer id, String name, String street, String house_No, String place,
  @Email String email, @Pattern(regexp = "(^$|[0-9]{10})") String ph_Number) {
super();
this.id = id;
this.name = name;
this.street = street;
this.house_No = house_No;
this.place = place;
this.email = email;
this.ph_Number = ph_Number;
}

//constructor
public CustomerEntity() {}

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
private String name;
private String street;
private String house_No;
private String place;
@Email
private String email;
@Pattern(regexp = "(^$|[0-9]{10})")
private String ph_Number;
}

Controller端点

@PostMapping("/createCust")
public ResponseEntity<CustomerEntity> createCust(@Valid @RequestBody CustomerEntity cust) {
CustomerEntity customer = custService.createCust(cust);
return ResponseEntity.status(HttpStatus.OK).body(customer);
}

Service代码

public CustomerEntity createCust(CustomerEntity cust) {
return custRepo.save(cust);
}

错误信息

java.lang.AssertionError: No value at JSON path "$.id"  
at org.springframework.test.util.JsonPathExpectationsHelper.evaluateJsonPath(JsonPathExpectationsHelper.java:302) 
at org.springframework.test.util.JsonPathExpectationsHelper.assertValue(JsonPathExpectationsHelper.java:99) 
at org.springframework.test.web.servlet.result.JsonPathResultMatchers.lambda$value$2(JsonPathResultMatchers.java:111) 
at org.springframework.test.web.servlet.MockMvc$1.andExpect(MockMvc.java:214) 
at com.rupesh.assesment.carlease.controller.CustomerControllerTest.testCreateCar(CustomerControllerTest.java:57) 
at java.base/java.lang.reflect.Method.invoke(Method.java:580)  
at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)  
at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)  
Caused by: java.lang.IllegalArgumentException: json can not be null or empty  
at com.jayway.jsonpath.internal.Utils.notEmpty(Utils.java:401)  
at com.jayway.jsonpath.JsonPath.read(JsonPath.java:390)  
at com.jayway.jsonpath.JsonPath.read(JsonPath.java:377)  
at org.springframework.test.util.JsonPathExpectationsHelper.evaluateJsonPath(JsonPathExpectationsHelper.java:299) 
... 7 more

排查与修复方案

1. Mock参数匹配问题

测试中手动构造的customer对象,和MockMvc将custJson转换后的CustomerEntity对象大概率不是同一个实例(默认equals比较地址),导致given(custService.createCust(customer))的匹配条件不触发,Service方法返回null,最终响应体为空,触发json can not be null or empty异常。

修复方式:

  • 使用any(CustomerEntity.class)匹配任意CustomerEntity实例:
    given(custService.createCust(any(CustomerEntity.class))).willReturn(customer2);
    
  • 或者重写CustomerEntity的equals和hashCode方法,确保属性一致时对象相等;
  • 也可以用ArgumentCaptor捕获请求中的对象,再验证属性:
    ArgumentCaptor<CustomerEntity> captor = ArgumentCaptor.forClass(CustomerEntity.class);
    given(custService.createCust(captor.capture())).willReturn(customer2);
    // 后续可以验证captor.getValue()的属性是否符合预期
    

2. 确保返回对象包含ID值

测试中customer2必须明确设置id属性为1,否则返回的CustomerEntity没有id字段,JSON序列化后自然找不到$.id:

CustomerEntity customer2 = new CustomerEntity();
customer2.setId(1); // 必须设置id
customer2.setName("John Doe");
// 其他属性也按预期设置

3. 检查请求路径是否匹配

测试中请求路径是/api/createCust,但Controller的@PostMapping是/createCust,路径不匹配会导致请求返回404,响应体为空,同样触发错误。将测试中的路径改为/createCust,或者在Controller类上添加@RequestMapping("/api")注解。

4. 实体类序列化问题

Spring MVC返回对象时依赖getter方法进行JSON序列化,如果CustomerEntity没有为id及其他属性添加getter方法,序列化后的JSON会缺失对应字段。为所有私有属性添加getter方法(必要时添加setter):

public Integer getId() {
    return id;
}

public void setId(Integer id) {
    this.id = id;
}

// 其他属性的getter/setter

内容的提问来源于stack exchange,提问作者Rupesh SA

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 07:20:08