为何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
相关产品推荐
相关产品推荐

