前面的文章中已經介紹過了如果獲得響應數據,接下來我們來介紹一下應該如何來驗證這些獲得的響應數據,比如驗證狀態碼、狀態行、cookies、header、content-type以及body體。
1.驗證響應體(Response Body)
關於響應體的驗證前面的JSON例子和XML例子中已經做過詳細的介紹,這里就不再介紹了。
我們也可以使用映射來做,將響應體映射到一個java對象中,關於對象映射前面也已經介紹過了,這里就不再介紹了。
2.驗證cookies
1 get("/x").then().assertThat().cookie("cookieName", "cookieValue"). .. 2 get("/x").then().assertThat().cookies("cookieName1", "cookieValue1", "cookieName2", "cookieValue2"). .. 3 get("/x").then().assertThat().cookies("cookieName1", "cookieValue1", "cookieName2", containsString("Value2")). ..
3.驗證狀態碼以及狀態行(Status and StatusLine)
1 get("/x").then().assertThat().statusCode(200). .. 2 get("/x").then().assertThat().statusLine("something"). .. 3 get("/x").then().assertThat().statusLine(containsString("some")). ..
4.驗證頭部(Header)
1 get("/x").then().assertThat().header("headerName", "headerValue"). .. 2 get("/x").then().assertThat().headers("headerName1", "headerValue1", "headerName2", "headerValue2"). .. 3 get("/x").then().assertThat().headers("headerName1", "headerValue1", "headerName2", containsString("Value2")). ..
驗證頭部我們也可以使用映射功能來做,比如說,我們要驗證Content-Length頭部是否小於1000。那我們就可以使用映射功能首先將頭部的值轉化為int,然后在使用 Hamcrest matcher 進行驗證之前使用 Integer 封裝類:
1 get("/something").then().assertThat().header("Content-Length", Integer::parseInt, lessThan(1000));
5.驗證Content-Type
1 get("/x").then().assertThat().contentType(ContentType.JSON). ..
6.完全匹配body或content
1 get("/x").then().assertThat().body(equalTo("something")). ..
7.關聯型驗證(使用響應體中的數據去驗證響應體的另外一些部分)
我們可以使用響應體中的數據去驗證響應體的另外一些部分,比如,服務端返回下面Json文件:
1 { "userId" : "some-id", "href" : "http://localhost:8080/some-id" }
在上面的json文件中,我們可以注意到"href"屬性是以"userId"的值結尾的,假如我們想要驗證這樣的一個 href ,我們可以通過實現 io.restassured.matcher.ResponseAwareMatcher並且使用它:
1 get("/x").then().body("href", new ResponseAwareMatcher<Response>() { 2 public Matcher<?> matcher(Response response) { 3 return equalTo("http://localhost:8080/" + response.path("userId")); 4 } 5 });
如果我們使用的是Java 8 的話,我們還可以使用 lambda 表達式來做:
1 get("/x").then().body("href", response -> equalTo("http://localhost:8080/" + response.path("userId"));
io.restassured.matcher.RestAssuredMatchers 這個類中還定義了一些預定義的machers可以使用(或者 io.restassured.module.mockmvc.matcher.RestAssuredMockMvcMatchers類,如果我們使用的是Spring-mock-mvc 模型),比如說:
1 get("/x").then().body("href", endsWithPath("userId"));
RestAssuredMatchers 也可以與另外一個 RestAssuredMatchers 或者是 Hamcrest Matcher 進行組合來使用,例如:
1 get("/x").then().body("href", and(startsWith("http:/localhost:8080/"), endsWithPath("userId")));
這里的 and 方法是從 io.restassured.matcher.ResponseAwareMatcherComposer 類中靜態導入的。
8.驗證響應時間
rest-assured的2.8.0版本開始支持獲取響應時間,例如:
1 long timeInMs = get("/lotto").time()
或者也可以指定時間單位:
1 long timeInSeconds = get("/lotto").timeIn(SECONDS);
其中 SECONDS 是一個標准的 TimeUnit ,使用驗證DSL也可以驗證響應時間:
1 when(). 2 get("/lotto"). 3 then(). 4 time(lessThan(2000L)); // Milliseconds
或者:
1 when(). 2 get("/lotto"). 3 then(). 4 time(lessThan(2L), SECONDS);
注意,響應時間計算的執行需要JVM是熱部署的(例如,只是簡單的跑一個test來執行響應時間的衡量將會產生錯誤的結果)
需要注意的是,我們上面的響應時間只能做為一個參考,並不能非常精准的與服務器處理時間相關聯(因為響應時間將會包括http往返的時間和rest-assured處理時間等其他時間)。
9.路徑參數方式驗證
當請求路徑中包含有預定義的變量時,路徑參數是非常有用的,比如:
1 String someSubPath = "else"; 2 int index = 1; 3 get("/x").then().body("something.%s[%d]", withArgs(someSubPath, index), equalTo("some value")). ..
上面的例子將會斷言:請求體路徑"something.else[0]" 是否等於 "some value"。
另外一個用處是當我們的根路徑(root path)非常復雜時,又不想因為一些小的改變而使用重復的路徑,我們可以這樣做:
1 when(). 2 get("/x"). 3 then(). 4 root("filters.filterConfig[%d].filterConfigGroups.find { it.name == 'GroupName' }.includes"). 5 body(withArgs(0), hasItem("first")). 6 body(withArgs(1), hasItem("second")). 7 ..
路徑參數遵循的是Java的標准格式化語法。
注意:withArgs 方法需要從 io.restassured.RestAssured 類中靜態導入。
有時候當所有的參數都在根路徑(root path)中已經被指定時,不使用額外的參數來進行響應體的驗證也是非常有用的。這里就需要用到 withNoArgs 方法了,例如:
1 when(). 2 get("/jsonStore"). 3 then(). 4 root("store.%s", withArgs("book")). 5 body("category.size()", equalTo(4)). 6 appendRoot("%s.%s", withArgs("author", "size()")). 7 body(withNoArgs(), equalTo(4));