REST Assured 系列汇总 之 REST Assured 26 - ObjectNode作为request的payload
前面我们学习了用Jackson API创建JSON payload, 现在我们应用到Rest Assured中。
body(Object object)
当我们用Jackson API创建一个JSON Object,它的类型是ObjectNode类,它是一个Node映射到JSON内容中的JSON Object结构。
RequestSpecification接口有很多重写body() 方法,其中之一便是RequestSpecification body(Object object) 方法。这个方法会将传入的object自动系列化成JSON或XML发送给request。
Rest Assured中Serialization系列化规则
是否被系列化成JSON或XML取决于传入的Content-Type.
如果我们传入的Content-Type是application/json,那么Rest Assured将Object系列化成JSON。为了系列化成JSON,Rest Assured将查找class path中哪个JSON解析器有效。如果Jackson没有找到,它就找GSON。如果两都均没有找到,则抛出IllegalArgumentException ,表明“Cannot serialize because no JSON or XML serializer found in classpath.” 的异常
如果我们传入Content-Type是application/xml,Rest Assured将把Object系列化成XML并寻找JAXB libray。如果没有找到,则抛出IllegalArgumentException ,表明“Cannot serialize because no JSON or XML serializer found in classpath.”的异常
如果我们没有传任何Content-Type, Rest Assured首先会试着用Jackson library解析成JSON。如果Jackson没有找到,则会找GSON。如果两者均未找到,则用JAXB解析成XML。如果JAXB也没有找到,最后抛出一个异常。
注意:
以上规则只适用POST 和 PUT方法
所以当我们用Jackson API创建一个JSON payload时,我们可以将它直接传给body() 方法。最好在Request Specification中传入Content-Type,尽管Rest Assured会将payload解析成JSON或XML,但是API可能不理解paylaod的type。
实例:
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import io.restassured.RestAssured;
import io.restassured.http.ContentType;
import org.junit.Test;
public class UseCreatedJsonObjectUsingJacksonAPIPayload {
@Test
public void CreatingNestedJsonObjectTest(){
// Create an object to ObjectMapper
ObjectMapper objectMapper = new ObjectMapper();
// Creating Node that maps to JSON Object structures in JSON content
ObjectNode bookingDetails = objectMapper.createObjectNode();
// It is similar to map put method. put method is overloaded to accept different types of data
// String as field value
bookingDetails.put("firstname", "Jim");
bookingDetails.put("lastname", "Brown");
// integer as field value
bookingDetails.put("totalprice", 111);
// boolean as field value
bookingDetails.put("depositpaid", true);
bookingDetails.put("additionalneeds", "Breakfast");
// Duplicate field name. Will override value
bookingDetails.put("additionalneeds", "Lunch");
// Since requirement is to create a nested JSON Object
ObjectNode bookingDateDetails = objectMapper.createObjectNode();
bookingDateDetails.put("checkin", "2021-07-01");
bookingDateDetails.put("checkout", "2021-07-01");
// Since 2.4 , put(String fieldName, JsonNode value) is deprecated. So use either set(String fieldName, JsonNode value) or replace(String fieldName, JsonNode value)
bookingDetails.set("bookingdates", bookingDateDetails);
RestAssured.given()
.baseUri("https://restful-booker.herokuapp.com/booking")
// Pass JSON pay load directly
.contentType(ContentType.JSON)
.body(bookingDetails)
.log()
.all()
// WHEN
.when()
.post()
// THEN
.then()
.assertThat()
.statusCode(200)
.log()
.all();
}
}
输出:
Request method: POST
Request URI: https://restful-booker.herokuapp.com/booking
Proxy: <none>
Request params: <none>
Query params: <none>
Form params: <none>
Path params: <none>
Headers: Accept=*/*
Content-Type=application/json
Cookies: <none>
Multiparts: <none>
Body:
{
"firstname": "Jim",
"lastname": "Brown",
"totalprice": 111,
"depositpaid": true,
"additionalneeds": "Lunch",
"bookingdates": {
"checkin": "2021-07-01",
"checkout": "2021-07-01"
}
}
HTTP/1.1 200 OK
Server: Cowboy
Connection: keep-alive
X-Powered-By: Express
Content-Type: application/json; charset=utf-8
Content-Length: 191
Etag: W/"bf-HWaWncA4JvMYofNfWwEp8U979ho"
Date: Sat, 28 Aug 2021 07:10:08 GMT
Via: 1.1 vegur
{
"bookingid": 11,
"booking": {
"firstname": "Jim",
"lastname": "Brown",
"totalprice": 111,
"depositpaid": true,
"bookingdates": {
"checkin": "2021-07-01",
"checkout": "2021-07-01"
},
"additionalneeds": "Lunch"
}
}
Process finished with exit code 0