Spring Bootの@RestClientTestへのクイックガイド

1前書き

この記事は @ RestClientTest アノテーションの簡単な紹介です。

新しいアノテーションはあなたのSpringアプリケーションでのRESTクライアントのテストを単純化しスピードアップするのを助けます。

2 Spring Boot Pre-1.4 におけるRESTクライアントのサポート

Spring Bootは多くの自動設定されたSpring Beansに典型的な設定を提供する便利なフレームワークで、Springアプリケーションの設定に集中することが少なくなり、コードやビジネスロジックに集中することができます。

しかし、バージョン1.3では、RESTサービスクライアントを作成またはテストしたいときには、それほど多くの助けを得ることはできません。 RESTクライアントに対するそのサポートはそれほど深くはありません。

REST API用のクライアントを作成するには、 RestTemplate インスタンスが通常使用されます。通常は使用前に設定する必要があり、設定が変わる可能性があるため、Spring Bootは汎用的に設定された RestTemplate Beanを提供しません。

RESTクライアントのテストにも同じことが言えます。 Spring Boot 1.4.0より前のSpring RESTクライアントをテストする手順は、他のSpringベースのアプリケーションと大差がありませんでした。以下のように、 MockRestServiceServer インスタンスを作成し、それをテスト中の RestTemplate インスタンスにバインドし、それにリクエストに対するモックレスポンスを提供します。

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();

また、Springコンテナを初期化し、必要なコンポーネントだけがコンテキストにロードされるようにして、コンテキストのロード時間(したがってテストの実行時間)を短縮する必要があります。

3 Spring Boot 1.4 の新しいRESTクライアント機能

Spring Boot 1.4では、チームはRESTクライアントの作成とテストを単純化しスピードアップするために確固たる努力を払いました。

それでは、新機能をチェックしましょう。

3.1. プロジェクトにSpring Bootを追加する

まず、プロジェクトがSpring Boot 1.4.x以降を使用していることを確認する必要があります。

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

最新のリリースバージョンはhttps://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-parent[ここ]にあります。

3.2. RestTemplateBuilder

Spring Bootは、 RestTemplates を簡単に作成するための自動設定 RestTemplateBuilder と、 RestTemplateBuilder で構築されたクライアントをテストするための対応する @ RestClientTest アノテーションの両方をもたらします。 RestTemplateBuilder を自動注入して簡単なRESTクライアントを作成する方法は次のとおりです。

@Service
public class DetailsServiceClient {

    private final RestTemplate restTemplate;

    public DetailsServiceClient(RestTemplateBuilder restTemplateBuilder) {
        restTemplate = restTemplateBuilder.build();
    }

    public Details getUserDetails(String name) {
        return restTemplate.getForObject("/{name}/details",
          Details.class, name);
    }
}

RestTemplateBuilder インスタンスをコンストラクタに明示的に配線していないことに注意してください。これは、暗黙的なコンストラクタインジェクションと呼ばれる新しいSpring機能のおかげで可能になります。これについては、/whats-new-in-spring-4-3[この記事]で説明しています。

RestTemplateBuilder は、メッセージコンバータ、エラーハンドラ、URIテンプレートハンドラ、基本認証を登録するための便利なメソッドを提供し、必要に応じてその他のカスタマイザも使用します。

3.3. @ RestClientTest

RestTemplateBuilder を使用して構築されたこのようなRESTクライアントをテストするには、 @ RestClientTest というアノテーションを付けた SpringRunner 実行済みテストクラスを使用できます。このアノテーションは完全自動設定を無効にし、RESTクライアントテストに関連する設定、つまりJacksonまたはGSON自動設定と @ JsonComponent Beanのみを適用しますが、通常の @ Component Beanは適用しません。

@ RestClientTest は、JacksonおよびGSONのサポートが確実に自動設定されるようにし、さらに事前設定された RestTemplateBuilder および MockRestServiceServer インスタンスをコンテキストに追加します。テスト対象のBeanは、 @ RestClientTest アノテーションの value または components 属性で指定されます。

@RunWith(SpringRunner.class)
@RestClientTest(DetailsServiceClient.class)
public class DetailsServiceClientTest {

    @Autowired
    private DetailsServiceClient client;

    @Autowired
    private MockRestServiceServer server;

    @Autowired
    private ObjectMapper objectMapper;

    @Before
    public void setUp() throws Exception {
        String detailsString =
          objectMapper.writeValueAsString(new Details("John Smith", "john"));

        this.server.expect(requestTo("/john/details"))
          .andRespond(withSuccess(detailsString, MediaType.APPLICATION__JSON));
    }

    @Test
    public void whenCallingGetUserDetails__thenClientMakesCorrectCall()
      throws Exception {

        Details details = this.client.getUserDetails("john");

        assertThat(details.getLogin()).isEqualTo("john");
        assertThat(details.getName()).isEqualTo("John Smith");
    }
}

まず、 @ RunWith(SpringRunner.class) アノテーションを追加して、このテストが SpringRunner で実行されることを確認する必要があります。

  • それで、何が新しいのですか?**

  • 最初** - @ RestClientTest アノテーションを使用すると、テスト対象の正確なサービスを指定できます。この場合は DetailsS​​erviceClient クラスです。このサービスはテストコンテキストにロードされますが、それ以外はすべて除外されます。

これにより、テスト内で DetailsS​​erviceClient インスタンスを自動配線し、他のすべてを外部に残しておくことができます。これにより、コンテキストのロードが高速化されます。

  • Second ** - MockRestServiceServer インスタンスも @ RestClientTest アノテーション付きテスト用に設定されているので(そして私たちの場合は DetailsS​​erviceClient インスタンスにバインドされているので)、単純にそれを注入して使用することができます。

  • 最後** - JSONの @ RestClientTest のサポートにより、Jacksonの ObjectMapper インスタンスをインジェクトして__MockRestServiceServerの模擬回答値を準備することができます。

やらなければいけないことは、私たちのサービスへの呼び出しを実行し、結果を検証することだけです。

4結論

この記事では、Springで構築されたRESTクライアントの簡単で素早いテストを可能にする新しい @ RestClientTest アノテーションについて説明しました。

この記事のソースコードはhttps://github.com/eugenp/tutorials/tree/master/spring-boot-client[on GitHub]にあります。

前の投稿:Java Weekly、第228号
次の投稿:Spring Bootで@JsonComponentを使う