RestTestClient
RestTestClient は、サーバーアプリケーションのテスト用に設計された HTTP クライアントです。Spring の RestClient をラップし、リクエストの実行に使用しますが、レスポンスの検証用にテストファサードを公開しています。RestTestClient はエンドツーエンドの HTTP テストに使用できます。また、MockMvc を介して、サーバーを実行せずに Spring MVC アプリケーションをテストすることもできます。
セットアップ
RestTestClient をセットアップするには、バインドするサーバー設定を選択する必要があります。これは、MockMvc の複数の設定から選択することも、ライブサーバーへの接続を選択することもできます。
コントローラーにバインド
この設定により、サーバーを実行せずに、モックリクエストおよびレスポンスオブジェクトを介して特定のコントローラーをテストできます。
Java
Kotlin
RestTestClient client =
RestTestClient.bindToController(new TestController()).build();val client = RestTestClient.bindToController(TestController()).build()ApplicationContext にバインド
このセットアップにより、Spring MVC インフラストラクチャとコントローラー宣言を使用して Spring 構成を読み込み、サーバーを実行せずに、モックリクエストおよびレスポンスオブジェクトを介してリクエストを処理できるようになります。
Java
Kotlin
@SpringJUnitConfig(WebConfig.class) (1)
class MyTests {
RestTestClient client;
@BeforeEach
void setUp(ApplicationContext context) { (2)
client = RestTestClient.bindToApplicationContext(context).build(); (3)
}
}| 1 | ロードする構成を指定します |
| 2 | 構成を注入する |
| 3 | RestTestClient を作成する |
@SpringJUnitConfig(WebConfig::class) (1)
class MyTests {
lateinit var client: RestTestClient
@BeforeEach
fun setUp(context: ApplicationContext) { (2)
client = RestTestClient.bindToApplicationContext(context).build() (3)
}
}| 1 | ロードする構成を指定します |
| 2 | 構成を注入する |
| 3 | RestTestClient を作成する |
ルーター関数にバインド
この設定により、サーバーを実行せずに、モックリクエストオブジェクトとレスポンスオブジェクトを介して関数エンドポイントをテストできます。
Java
Kotlin
RouterFunction<?> route = ...
client = RestTestClient.bindToRouterFunction(route).build();val route: RouterFunction<*> = ...
val client = RestTestClient.bindToRouterFunction(route).build()サーバーにバインド
このセットアップは、実行中のサーバーに接続して、完全なエンドツーエンドの HTTP テストを実行します。
Java
Kotlin
client = RestTestClient.bindToServer().baseUrl("http://localhost:8080").build();client = RestTestClient.bindToServer().baseUrl("http://localhost:8080").build()クライアント構成
前述のサーバー設定オプションに加えて、ベース URL、デフォルトヘッダー、クライアントフィルターなど、クライアントオプションも設定できます。これらのオプションは、最初の bindTo 呼び出しの直後から、以下のようにすぐに利用できます。
Java
Kotlin
client = RestTestClient.bindToController(new TestController())
.baseUrl("/test")
.build();client = RestTestClient.bindToController(TestController())
.baseUrl("/test")
.build()テストの作成
RestClient と RestTestClient は、exchange() の呼び出しまでは API は同じです。その後、RestTestClient はレスポンスを検証するための 2 つの代替方法を提供します。
組み込みアサーションは、期待される チェーンに基づいてリクエストワークフローを継承します。
AssertJ 統合は
assertThat()ステートメントを介してレスポンスを検証します
組み込みアサーション
To use the built-in assertions, remain in the workflow after the call to exchange(), and use one of the expectation methods. For example:
Java
Kotlin
client.get().uri("/persons/1")
.accept(MediaType.APPLICATION_JSON)
.exchange()
.expectStatus().isOk()
.expectHeader().contentType(MediaType.APPLICATION_JSON);client.get().uri("/persons/1")
.accept(MediaType.APPLICATION_JSON)
.exchange()
.expectStatus().isOk()
.expectHeader().contentType(MediaType.APPLICATION_JSON) いずれかが失敗した場合でもすべての期待値を表明したい場合は、複数のチェーン化された expect*(..) 呼び出しの代わりに expectAll(..) を使用できます。この機能は、AssertJ でのソフトアサーションのサポートおよび JUnit Jupiter での assertAll() のサポートに似ています。
Java
Kotlin
client.get().uri("/persons/1")
.accept(MediaType.APPLICATION_JSON)
.exchange()
.expectAll(
spec -> spec.expectStatus().isOk(),
spec -> spec.expectHeader().contentType(MediaType.APPLICATION_JSON)
);client.get().uri("/persons/1")
.accept(MediaType.APPLICATION_JSON)
.exchange()
.expectAll(
{ spec -> spec.expectStatus().isOk() },
{ spec -> spec.expectHeader().contentType(MediaType.APPLICATION_JSON) }
)次に、次のいずれかを使用してレスポンス本文をデコードすることを選択できます。
expectBody(Class<T>): 単一のオブジェクトにデコードします。expectBody(): JSON コンテンツまたは空のボディの場合はbyte[]にデコードします。
組み込みのアサーションが不十分な場合は、代わりにオブジェクトを使用して、他のアサーションを実行できます。
Java
Kotlin
client.get().uri("/persons/1")
.exchange()
.expectStatus().isOk()
.expectBody(Person.class)
.consumeWith(result -> {
// custom assertions (for example, AssertJ)...
});client.get().uri("/persons/1")
.exchange()
.expectStatus().isOk()
.expectBody<Person>()
.consumeWith {
// custom assertions (for example, AssertJ)...
} または、ワークフローを終了して EntityExchangeResult を取得することもできます。
Java
Kotlin
EntityExchangeResult<Person> result = client.get().uri("/persons/1")
.exchange()
.expectStatus().isOk()
.expectBody(Person.class)
.returnResult();val result = client.get().uri("/persons/1")
.exchange()
.expectStatus().isOk
.expectBody<Person>()
.returnResult() ジェネリクスを使用してターゲット型にデコードする必要がある場合は、Class<T> ではなく ParameterizedTypeReference (Javadoc) を受け入れるオーバーロードメソッドを探します。 |
コンテンツなし
レスポンスに内容が含まれることが予想されない場合は、次のように主張できます。
Java
Kotlin
client.post().uri("/persons")
.body(person)
.exchange()
.expectStatus().isCreated()
.expectBody().isEmpty();client.post().uri("/persons")
.body(person)
.exchange()
.expectStatus().isCreated()
.expectBody().isEmpty()レスポンスコンテンツを無視する場合、以下はアサーションなしでコンテンツをリリースします。
Java
Kotlin
client.get().uri("/persons/123")
.exchange()
.expectStatus().isNotFound()
.expectBody(Void.class);client.get().uri("/persons/123")
.exchange()
.expectStatus().isNotFound
.expectBody<Unit>()JSON コンテンツ
ターゲット型なしで expectBody() を使用して、高レベルのオブジェクトを介してではなく、生のコンテンツに対してアサーションを実行できます。
JSONAssert (英語) で完全な JSON コンテンツを確認するには:
Java
Kotlin
client.get().uri("/persons/1")
.exchange()
.expectStatus().isOk()
.expectBody()
.json("{\"name\":\"Jane\"}")client.get().uri("/persons/1")
.exchange()
.expectStatus().isOk()
.expectBody()
.json("{\"name\":\"Jane\"}")JSONPath [GitHub] (英語) で JSON コンテンツを確認するには:
Java
Kotlin
client.get().uri("/persons")
.exchange()
.expectStatus().isOk()
.expectBody()
.jsonPath("$[0].name").isEqualTo("Jane")
.jsonPath("$[1].name").isEqualTo("Jason");client.get().uri("/persons")
.exchange()
.expectStatus().isOk()
.expectBody()
.jsonPath("$[0].name").isEqualTo("Jane")
.jsonPath("$[1].name").isEqualTo("Jason")AssertJ 統合
RestTestClientResponse は AssertJ 統合のメインエントリポイントです。これは、assertThat() 文の使用を可能にするために、交換の ResponseSpec をラップする AssertProvider です。例:
Java
Kotlin
ResponseSpec spec = client.get().uri("/persons").exchange();
RestTestClientResponse response = RestTestClientResponse.from(spec);
assertThat(response).hasStatusOk();
assertThat(response).hasContentTypeCompatibleWith(MediaType.TEXT_PLAIN);
// ...val spec = client.get().uri("/persons").exchange()
val response = RestTestClientResponse.from(spec)
assertThat(response).hasStatusOk()
assertThat(response).hasContentTypeCompatibleWith(MediaType.TEXT_PLAIN)
// ... 最初に組み込みワークフローを使用し、その後 ExchangeResult を取得して AssertJ でラップし、続行することもできます。例:
Java
Kotlin
ExchangeResult result = client.get().uri("/persons").exchange()
. // ...
.returnResult();
RestTestClientResponse response = RestTestClientResponse.from(result);
assertThat(response).hasStatusOk();
assertThat(response).hasContentTypeCompatibleWith(MediaType.TEXT_PLAIN);
// ...val result = client.get().uri("/persons").exchange()
. // ...
.returnResult()
val response = RestTestClientResponse.from(spec)
assertThat(response).hasStatusOk()
assertThat(response).hasContentTypeCompatibleWith(MediaType.TEXT_PLAIN)
// ...