知識庫 / HTTP Client-Side RSS 訂閱

使用 REST-assured 獲取和驗證響應數據

HTTP Client-Side,REST,Spring,Testing
HongKong
7
03:51 AM · Dec 06 ,2025

1. 概述

本教程將介紹如何使用 REST Assured 測試 REST 服務,重點是捕獲和驗證來自我們 REST API 的響應數據

2. 測試類設置

在之前的教程中,我們已經探討了 REST Assured 的一般用法,並展示瞭如何操作請求頭、Cookie 和參數。

在此基礎上,我們添加了一個簡單的 REST 控制器,AppController,它內部調用了一個服務,AppService。我們將使用這些類在我們的測試示例中。

為了創建我們的測試類,我們需要進行一些設置。由於我們已經在 classpath 中包含了 spring-boot-starter-test,因此我們可以輕鬆地利用 Spring 測試實用程序。

首先,讓我們創建一個 AppControllerIntegrationTest 類的基本框架:

@RunWith(SpringRunner.class)
@SpringBootTest
@TestConfiguration
public class AppControllerIntegrationTest {

    // TODO: Add your test methods here
}
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class AppControllerIntegrationTest {

    @LocalServerPort
    private int port;

    private String uri;

    @PostConstruct
    public void init() {
        uri = "http://localhost:" + port;
    }

    @MockBean
    AppService appService;

     //test cases
}

在本次 JUnit 測試中,我們使用了一些 Spring 相關的註解對我們的類進行了標註,從而在隨機可用的端口上啓動應用程序。在 <em @PostConstruct</em> 中,我們捕獲了我們將用於進行 REST 調用時的完整 URI。

我們還使用了 <em @MockBean</em><em AppService</em> 進行標註,因為我們需要對該類的方法調用進行模擬。

3. 驗證 JSON 響應

JSON 是 REST API 中用於交換數據的最常見格式。響應可以包含單個 JSON 對象或多個 JSON 對象數組。本節將探討這兩種情況。

3.1. 單個 JSON 對象

假設我們需要測試 /movie/{id} 端點,該端點如果找到 id 則返回一個 Movie JSON 對象。

我們將使用 Mockito 框架來模擬 AppService 調用並返回一些模擬數據:

@Test
public void givenMovieId_whenMakingGetRequestToMovieEndpoint_thenReturnMovie() {

    Movie testMovie = new Movie(1, "movie1", "summary1");
    when(appService.findMovie(1)).thenReturn(testMovie);

    get(uri + "/movie/" + testMovie.getId()).then()
      .assertThat()
      .statusCode(HttpStatus.OK.value())
      .body("id", equalTo(testMovie.getId()))
      .body("name", equalTo(testMovie.getName()))
      .body("synopsis", notNullValue());
}

首先,我們模擬了 appService.findMovie(1) 調用並返回一個對象。然後,我們使用 REST Assured 提供的 get() 方法構建了 REST URL,用於發起 GET 請求。最後,我們執行了四次斷言。

首先,我們檢查了響應狀態碼和 body 中的元素。我們使用 Hamcrest 驗證期望的值。

此外,請注意如果響應 JSON 是嵌套的,可以使用 dot 運算符來測試嵌套鍵,例如 “key1.key2.key3”.

3.2. 在驗證後提取 JSON 響應

在某些情況下,我們可能需要提取驗證後的響應以執行進一步的操作。

我們可以使用 extract() 方法將 JSON 響應提取到一個類中:

Movie result = get(uri + "/movie/" + testMovie.getId()).then()
  .assertThat()
  .statusCode(HttpStatus.OK.value())
  .extract()
  .as(Movie.class);
assertThat(result).isEqualTo(testMovie);

在本示例中,我們使用 REST Assured 提取 JSON 響應至一個 Movie 對象,然後對其進行了斷言。

我們還可以使用 extract().asString() API 提取整個響應至一個 String 對象:

String responseString = get(uri + "/movie/" + testMovie.getId()).then()
  .assertThat()
  .statusCode(HttpStatus.OK.value())
  .extract()
  .asString();
assertThat(responseString).isNotEmpty();

最後,我們可以從響應 JSON 中提取特定的字段

讓我們來看一個用於測試 POST API 的測試,該 API 期望一個 Movie JSON 負載體,並在成功插入時返回相同的內容:

@Test
public void givenMovie_whenMakingPostRequestToMovieEndpoint_thenCorrect() {
    Map<String, String> request = new HashMap<>();
    request.put("id", "11");
    request.put("name", "movie1");
    request.put("synopsis", "summary1");

    int movieId = given().contentType("application/json")
      .body(request)
      .when()
      .post(uri + "/movie")
      .then()
      .assertThat()
      .statusCode(HttpStatus.CREATED.value())
      .extract()
      .path("id");
    assertThat(movieId).isEqualTo(11);
}

我們首先創建了需要通過 POST 請求的請求對象。隨後,我們使用 path() 方法從返回的 JSON 響應中提取 id 字段。

3.3. JSON 數組

我們可以通過驗證響應是否為 JSON 數組來進一步確認。

@Test
public void whenCallingMoviesEndpoint_thenReturnAllMovies() {

Set<Movie> movieSet = new HashSet<>();
movieSet.add(new Movie(1, "movie1", "summary1"));
movieSet.add(new Movie(2, "movie2", "summary2"));
when(appService.getAll()).thenReturn(movieSet);

get(uri + "/movies").then()
    .statusCode(HttpStatus.OK.value())
    .assertThat()
    .body("size()", is(2));
}

據此,我們首先使用一些數據對 appService.getAll() 方法進行了模擬,並向我們的端點發送了請求。 然後,我們斷言了響應數組的 statusCodesize

這同樣可以通過提取方式實現:

Movie[] movies = get(uri + "/movies").then()
  .statusCode(200)
  .extract()
  .as(Movie[].class);
assertThat(movies.length).isEqualTo(2);

3.4. 將響應 JSON 反序列化為 List<POJO></h3

在上一節中,我們使用 .as(Movie[].class) 將 JSON 電影數組反序列化為 Java 數組中的 Movie 對象。雖然這種方法有效,但在 Java 中,使用泛型 List 是一種更具表現力的做法。

但是,由於 Java 的類型擦除機制,我們無法直接將 JSON 反序列化為泛型類型,如 List.class

為了解決這個問題,我們使用 REST Assured 中的 TypeRef 類,這是一個抽象類,它允許我們向反序列器傳遞泛型類型信息:

@Test
public void givenSetMovie_whenCallingMoviesEndpoint_thenReturnAllMoviesAsList() {
    Set<Movie> movieSet = new HashSet<>();
    movieSet.add(new Movie(1, "movie1", "summary1"));
    movieSet.add(new Movie(2, "movie2", "summary2"));
    when(appService.getAll()).thenReturn(movieSet);

    List<Movie> movies = get(uri + "/movies").then()
        .statusCode(200)
        .extract()
        .as(new TypeRef<List<Movie>>() {});

    assertThat(movies.size()).isEqualTo(2);
}

因此,通過創建匿名內部類並使其擴展 TypeRef<List>,我們明確地告訴 REST Assured 我們希望將響應體反序列化為的精確泛型類型。這使得響應體被簡潔地反序列化為 List,這比 Movie[] 數組要更容易處理。

4. 驗證響應頭和 Cookie

我們可以使用同名的方法來驗證響應頭或 Cookie:

@Test
public void whenCallingWelcomeEndpoint_thenCorrect() {
    get(uri + "/welcome").then()
        .assertThat()
        .header("sessionId", notNullValue())
        .cookie("token", notNullValue());
}

我們還可以單獨提取標題和 Cookie:

Response response = get(uri + "/welcome");

String headerName = response.getHeader("sessionId");
String cookieValue = response.getCookie("token");
assertThat(headerName).isNotBlank();
assertThat(cookieValue).isNotBlank();

5. 驗證文件

如果我們的 REST API 返回一個文件,我們可以使用 asByteArray() 方法來提取響應:

File file = new ClassPathResource("test.txt").getFile();
long fileSize = file.length();
when(appService.getFile(1)).thenReturn(file);

byte[] result = get(uri + "/download/1").asByteArray();

assertThat(result.length).isEqualTo(fileSize);

在這裏,我們首先模擬了<em >appService.getFile(1)</em >的調用,使其返回位於我們src/test/resources路徑下的文本文件。然後,我們調用了我們的端點並提取了響應,以`byte[]的形式,隨後我們斷言該值與預期值一致。

6. 結論

在本教程中,我們探討了使用 REST Assured 從我們的 REST API 中捕獲和驗證響應的不同方法。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.