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

JUnit断言失败:期望<200>实际为<400>,Controller层POST测试问题

解决JUnit测试POST接口返回400 Bad Request的问题

看起来你遇到了一个典型的「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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:22:19