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

为何REST Assured请求与Postman结果不一致?(返回403/400而非201)

问题:REST Assured测试POST请求失败,Postman可正常运行

我们在大学小组项目中基于Micronaut框架开发了数据管理REST API,需要用REST Assured做测试。Postman向路径/user/38/devices发送POST请求(请求体为{"name":"Test Device"},通过Bearer令牌认证)能成功返回201状态码,但编写的REST Assured代码始终无法得到相同结果:

  • 首次尝试返回403
  • 调整请求头后返回400
  • 参照Postman生成的cURL修改代码也没解决

我是第一次接触这类技术,不清楚问题所在。

首次尝试代码

@Test
public void devicePostTest(RequestSpecification spec) {
    spec.given().auth().oauth2(bearerToken).param("name", "Test Device")
            .when().post("/user/38/devices")
            .then().statusCode(201);
}

调整后代码

@Test
public void devicePostTest(RequestSpecification spec) {
    spec.given().headers("Authorization", "Bearer " + bearerToken,"Content-Type", ContentType.JSON,
                "Accept", ContentType.JSON)
            .param("name", "Test Device")
            .when().post("/user/38/devices")
            .then().statusCode(201);
}

Postman生成的cURL

curl --location 'http://localhost:9080/user/38/devices' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer *bearerToken*' \
--data '{
    "name":"Test Device"
}'

问题原因与解决方案

核心问题是参数传递方式错误:你用.param()方法传递name参数,这个方法会把参数放到URL的查询字符串里(比如/user/38/devices?name=Test+Device),但Postman是把参数放到JSON请求体中,这和API的接收逻辑不匹配,导致400错误;而首次的403大概率是因为请求格式不符合API要求,触发了认证或请求校验拦截。

正确的REST Assured代码应该这样写:

方式1:直接传递JSON字符串

@Test
public void devicePostTest(RequestSpecification spec) {
    spec.given()
            .auth().oauth2(bearerToken) // 标准的Bearer认证写法,无需手动拼接Header
            .contentType(ContentType.JSON) // 指定请求体为JSON格式
            .body("{\"name\":\"Test Device\"}") // 传递JSON请求体
            .when().post("/user/38/devices")
            .then().statusCode(201);
}

方式2:用实体类自动序列化(更优雅)

如果项目中有对应的实体类,REST Assured会自动帮你把对象序列化为JSON:

// 假设存在对应的Device实体类
class Device {
    private String name;

    public Device(String name) {
        this.name = name;
    }

    // 需提供getter/setter,或用Lombok简化
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

@Test
public void devicePostTest(RequestSpecification spec) {
    spec.given()
            .auth().oauth2(bearerToken)
            .contentType(ContentType.JSON)
            .body(new Device("Test Device")) // 直接传入对象,自动转JSON
            .when().post("/user/38/devices")
            .then().statusCode(201);
}

另外,Accept请求头如果API没有强制要求可以省略,REST Assured会默认处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 09:34:54