RESTを使用した応答データの取得と検証

1. 概要

このチュートリアルでは、* REST APIからの応答データの取得と検証*に焦点を当て、RESTを使用してRESTサービスをテストする方法について説明します。

2. テストクラスのセットアップ

以前のチュートリアルでは、https://www.baeldung.com/rest-assured-tutorial [REST-assured一般]を調査し、リクエストを操作する方法を示しましたlink:/ rest-assured-header-cookie-parameter [ヘッダー、Cookie、およびパラメーター]。
この既存のセットアップに基づいて、サービス_AppService_を内部的に呼び出す単純なRESTコントローラー_AppController_を追加しました。 これらのクラスをテスト例で使用します。
テストクラスを作成するには、もう少しセットアップを行う必要があります。 クラスパスに_spring-boot-starter-test_があるため、Springテストユーティリティを簡単に活用できます。
まず、_AppControllerIntegrationTest_クラスのスケルトンを作成しましょう。
@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固有の注釈を使用してクラスに注釈を付けました。 _ @ PostConstruct_で、REST呼び出しを行う完全なURIをキャプチャしました。
このクラスでメソッド呼び出しをモックする必要があるため、_ @ MockBean_ on _AppService_も使用しました。

3. JSONレスポンスの検証

JSONは、データを交換するためにREST APIで使用される最も一般的な形式です。 応答は、単一のJSONオブジェクトまたはJSONオブジェクトの配列で構成できます。 このセクションでは両方を見ていきます。

3.1. 単一のJSONオブジェクト

_ / movie / \ {id} _エンドポイントをテストする必要があるとします。エンドポイントは、_id_が見つかった場合に_Movie_ JSONオブジェクトを返します。
link:/mockito-series[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)_呼び出しをモックしてオブジェクトを返しました。 次に、GET要求を作成するためにRESTが提供する_get()_メソッドでREST URLを構築しました。 最後に、4つのアサーションを作成しました。
最初に、*応答ステータスコードをチェックしてから、_body_要素をチェックしました*。 link:/java-junit-hamcrest-guide[Hamcrest]を使用して、期待される値をアサートしています。
また、応答JSONがネストされている場合は、_“key1.key2.key3â€_のような_dot_演算子を使用してネストされたキーをテストできることに注意してください。

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);
この例では、_Movie_オブジェクトへのJSON応答を抽出するようにRESTで保証し、抽出したオブジェクトでアサートしました。
  • extract()。asString() APIを使用して、_String、_への応答全体を抽出することもできます。*

String responseString = get(uri + "/movie/" + testMovie.getId()).then()
  .assertThat()
  .statusCode(HttpStatus.OK.value())
  .extract()
  .asString();
assertThat(responseString).isNotEmpty();
最後に、*応答JSONから特定のフィールドを抽出することもできます*。
_Movie_ JSONボディを期待し、正常に挿入された場合に同じものを返すPOST APIのテストを見てみましょう。
@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()_をデータでモックし、エンドポイントにリクエストを行いました。 *次に、応答配列の_statusCode_および_size_をアサートしました。*
これも抽出を介して実行できます。
Movie[] movies = get(uri + "/movies").then()
  .statusCode(200)
  .extract()
  .as(Movie[].class);
assertThat(movies.length).isEqualTo(2);
同じ名前のメソッドを使用して、応答のヘッダーまたは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);
ここでは、最初にm_appService.getFile(1)_をモックして、_src / test / resources_パスにあるテキストファイルを返します。 次に、エンドポイントへの呼び出しを行い、_byte [] _で応答を抽出し、それを期待値を持つようにアサートしました。

6. 結論

このチュートリアルでは、RESTを使用してREST APIからの応答をキャプチャおよび検証するさまざまな方法を検討しました。
いつものように、この記事のコードはhttps://github.com/eugenp/tutorials/tree/master/testing-modules/rest-assured[Github上]で入手できます。