クライアントアプリケーションのテスト

クライアント側のテストを使用して、RestTemplate を内部的に使用するコードをテストできます。予想されるリクエストを宣言し、「スタブ」レスポンスを提供することにより、コードの分離テスト(サーバーを実行せずに)に集中できるようになります。次の例は、その方法を示しています。

  • Java

  • Kotlin

RestTemplate restTemplate = new RestTemplate();

MockRestServiceServer mockServer = MockRestServiceServer.bindTo(restTemplate).build();
mockServer.expect(requestTo("/greeting")).andRespond(withSuccess());

// Test code that uses the above RestTemplate ...

mockServer.verify();
val restTemplate = RestTemplate()

val mockServer = MockRestServiceServer.bindTo(restTemplate).build()
mockServer.expect(requestTo("/greeting")).andRespond(withSuccess())

// Test code that uses the above RestTemplate ...

mockServer.verify()

上記の例では、MockRestServiceServer (クライアント側の REST テストの中心クラス)は、RestTemplate を、期待に反して実際のリクエストをアサートし、「スタブ」レスポンスを返すカスタム ClientHttpRequestFactory で構成します。この場合、/greeting へのリクエストが予想され、text/plain コンテンツを含む 200 レスポンスを返します。必要に応じて、追加の予想リクエストとスタブレスポンスを定義できます。予想されるリクエストとスタブレスポンスを定義する場合、RestTemplate は通常どおりクライアント側のコードで使用できます。テストの最後に、mockServer.verify() を使用して、すべての期待が満たされていることを確認できます。

デフォルトでは、リクエストは予想が宣言された順序で予想されます。サーバーの構築時に ignoreExpectOrder オプションを設定できます。この場合、すべての期待値が(順番に)チェックされ、特定のリクエストに一致するものが見つかります。つまり、リクエストは任意の順序で送信できます。次の例では、ignoreExpectOrder を使用しています。

  • Java

  • Kotlin

server = MockRestServiceServer.bindTo(restTemplate).ignoreExpectOrder(true).build();
server = MockRestServiceServer.bindTo(restTemplate).ignoreExpectOrder(true).build()

デフォルトでは、順序付けされていないリクエストでも、各リクエストは一度だけ実行できます。expect メソッドは、カウント範囲を指定する ExpectedCount 引数を受け入れるオーバーロードされたバリアントを提供します(たとえば、oncemanyTimesmaxminbetween など)。次の例では times を使用しています。

  • Java

  • Kotlin

RestTemplate restTemplate = new RestTemplate();

MockRestServiceServer mockServer = MockRestServiceServer.bindTo(restTemplate).build();
mockServer.expect(times(2), requestTo("/something")).andRespond(withSuccess());
mockServer.expect(times(3), requestTo("/somewhere")).andRespond(withSuccess());

// ...

mockServer.verify();
val restTemplate = RestTemplate()

val mockServer = MockRestServiceServer.bindTo(restTemplate).build()
mockServer.expect(times(2), requestTo("/something")).andRespond(withSuccess())
mockServer.expect(times(3), requestTo("/somewhere")).andRespond(withSuccess())

// ...

mockServer.verify()

ignoreExpectOrder が設定されていない場合(デフォルト)、リクエストは宣言の順序で予期される場合、その順序は予期されるリクエストの最初のものにのみ適用されることに注意してください。たとえば、"/something" が 2 回、続いて "/somewhere" が 3 回予想される場合、"/somewhere" へのリクエストがある前に "/something" へのリクエストがあるはずですが、その後の "/something" と "/somewhere" を除いて、リクエストはいつでも来ることができます。

上記のすべての代替として、クライアント側のテストサポートは、RestTemplate に構成して MockMvc インスタンスにバインドできる ClientHttpRequestFactory 実装も提供します。これにより、サーバーを実行せずに、実際のサーバー側ロジックを使用してリクエストを処理できます。次の例は、その方法を示しています。

  • Java

  • Kotlin

MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
this.restTemplate = new RestTemplate(new MockMvcClientHttpRequestFactory(mockMvc));

// Test code that uses the above RestTemplate ...
val mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build()
restTemplate = RestTemplate(MockMvcClientHttpRequestFactory(mockMvc))

// Test code that uses the above RestTemplate ...

場合によっては、レスポンスをモックする代わりに、リモートサービスへの実際の呼び出しを実行する必要があります。次の例は、ExecutingResponseCreator を介してそれを行う方法を示しています。

  • Java

  • Kotlin

RestTemplate restTemplate = new RestTemplate();

// Create ExecutingResponseCreator with the original request factory
ExecutingResponseCreator withActualResponse = new ExecutingResponseCreator(restTemplate.getRequestFactory());

MockRestServiceServer mockServer = MockRestServiceServer.bindTo(restTemplate).build();
mockServer.expect(requestTo("/profile")).andRespond(withSuccess());
mockServer.expect(requestTo("/quoteOfTheDay")).andRespond(withActualResponse);

// Test code that uses the above RestTemplate ...

mockServer.verify();
val restTemplate = RestTemplate()

// Create ExecutingResponseCreator with the original request factory
val withActualResponse = new ExecutingResponseCreator(restTemplate.getRequestFactory())

val mockServer = MockRestServiceServer.bindTo(restTemplate).build()
mockServer.expect(requestTo("/profile")).andRespond(withSuccess())
mockServer.expect(requestTo("/quoteOfTheDay")).andRespond(withActualResponse)

// Test code that uses the above RestTemplate ...

mockServer.verify()

前の例では、MockRestServiceServer がレスポンスをモックする別のものに置き換える前にRestTemplate の ClientHttpRequestFactory を使用して ExecutingResponseCreator を作成します。次に、2 種類のレスポンスで期待値を定義します。

  • /profile エンドポイントのスタブ 200 レスポンス (実際のリクエストは実行されません)

  • /quoteOfTheDay エンドポイントへの呼び出しによって取得されたレスポンス

2 番目のケースでは、以前にキャプチャーされた ClientHttpRequestFactory を介してリクエストが実行されます。これにより、たとえば次のようなレスポンスが生成されます。RestTemplate が最初に構成された方法に応じて、実際の リモートサーバーから取得されます。

静的インポート

サーバー側のテストと同様に、クライアント側のテスト用の流れるような API には、いくつかの静的インポートが必要です。それらは MockRest* を検索することで簡単に見つけることができます。Eclipse ユーザーは、MockRestRequestMatchers.* および MockRestResponseCreators.* を "Java" →「エディター」→「コンテンツアシスト」→「お気に入り」の Eclipse 設定で「お気に入りの静的メンバー」として追加する必要があります。これにより、静的メソッド名の最初の文字を入力した後にコンテンツアシストを使用できます。他の IDE(IntelliJ など)は、追加の構成を必要としない場合があります。静的メンバーでのコード補完のサポートを確認してください。

クライアント側の REST テストのその他の例

Spring MVC Test 独自のテストには、クライアント側の REST テストのサンプルテストが含 [GitHub] (英語) まれています。