JUnit断言失败:期望<200>实际为<400>,Controller层POST测试问题
看起来你遇到了一个典型的「Postman调用正常但JUnit测试报错」的问题,400状态码说白了就是你的测试请求格式不对,Spring没法正确解析。咱们一步步排查解决:
1. 先检查JUnit测试的请求构造是否规范
Postman里你是手动写JSON,很容易符合格式,但JUnit测试里如果没处理好对象序列化或者请求头,就会踩坑。比如用MockMvc的话,必须确保两个关键点:
- 设置正确的
Content-Type: application/json请求头 - 把Hello对象正确序列化为JSON字符串
给你个正确的测试示例,照着改就行:
@SpringBootTest @AutoConfigureMockMvc public class HelloResourceTest { @Autowired private MockMvc mockMvc; @Test public void testHelloPost() throws Exception { // 构造测试用的Hello对象 Hello testHello = new Hello(); testHello.setTitle("测试标题"); testHello.setValue("测试内容"); // 用Jackson把对象转成JSON字符串 ObjectMapper objectMapper = new ObjectMapper(); String requestBody = objectMapper.writeValueAsString(testHello); mockMvc.perform(post("/hello/post") .contentType(MediaType.APPLICATION_JSON) // 必须加这个头 .content(requestBody)) .andExpect(status().isOk()) .andExpect(jsonPath("$.title").value("测试标题")); } }
如果你的测试里没加contentType,或者直接把对象toString传进去了,Spring肯定解析不了,直接返回400。
2. 检查Hello类的序列化兼容性
Spring默认用Jackson处理JSON序列化,而Jackson要求被序列化的类必须有无参构造函数。Postman里你是直接传JSON,不需要实例化Hello对象,但JUnit测试里序列化/反序列化的时候必须要有无参构造,否则Jackson没法创建对象,直接报解析错误返回400。
给Hello类补个无参构造就行:
class Hello { private String title; private String value; // 必须加这个无参构造! public Hello() {} // 有参构造可以保留,不影响 public Hello(String title, String value) { this.title = title; this.value = value; } // 你的getter和setter方法 public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getValue() { return value; } public void setValue(String value) { this.value = value; } }
3. 排查是否有字段校验导致的错误
如果你的接口加了@Valid注解,或者Hello类的字段加了@NotBlank/@NotNull这类校验注解,那测试时必须给必填字段赋值,否则会因为校验失败返回400。比如:
// 接口里加了@Valid public Hello helloPost(@Valid @RequestBody Hello hello) { ... } // Hello类里加了校验 class Hello { @NotBlank(message = "标题不能为空") private String title; ... }
这种情况就给测试对象的所有必填字段都赋值,或者去掉不必要的校验(如果业务不需要的话)。
4. 打印请求详情,精准定位问题
如果上面的方法都没解决,那就直接打印请求和响应的详细日志,看看Spring到底报了啥错。在测试里加个andDo(print())就行:
mockMvc.perform(post("/hello/post") .contentType(MediaType.APPLICATION_JSON) .content(requestBody)) .andDo(print()) // 打印请求、响应的所有细节 .andExpect(status().isOk());
日志里会明确告诉你错误原因,比如“JSON parse error: Cannot construct instance of Hello (no Creators, like default construct, exist)”,看到这个就知道是缺无参构造了,直接补就行。
内容的提问来源于stack exchange,提问作者SpringUser

