Spring Restコントローラーのテスト:シンプルで、短く、信頼性が高い。 Spring Securityテスト+ JSONマッチャー





こんにちは

ネイティブJSONマッチャー、Spring Security 4.0に最近組み込まれたSpring Security Testの使用、およびサービスをテストする際のトランザクションの拒否により、テストがより簡単で信頼性の高いものになります。



Topjavaコース(Maven / Spring / Security / JPA(Hibernate)/ Rest(Jackson)/ Bootstrap(CSS)/ jQuery + plugins)でアプリケーションを作成するときにこのアプローチを使用しました。プロジェクトソースコードはgithubで取得できます



この記事は、 Spring RESTコントローラーのテストに関するまだ別のチュートリアルではありません。また、この記事を既に理解していることをお勧めします。



Spring Pet Clinicの道をたどる以前の出版物で、取引を拒否することの利点についてすでに書いています Maven / Spring Context / Spring Test / Spring ORM / Spring Data JPA 。 @Transactionを使用することの上記の欠点に加えて、データベースに対してサービスメソッドを実行するとき(たとえば、hibernate.use_sql_commentsが有効になっているとき)に実際のクエリを表示できないようにすることもできます。



ここで、Spring RESTコントローラーをテストするのが簡単で、短く、信頼性が高い方法を書きます。



春のセキュリティテスト



Spring Security 4.0のリリース前は、これは、改善されたテストサポートとしてSpring Security 4.0に含まれていた別のプロジェクトでした。

これは中央のMavenリポジトリにあり、次のように接続します。

<properties> <spring-security.version>4.0.1.RELEASE</spring-security.version> </properties><dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-test</artifactId> <version>${spring-security.version}</version> </dependency>
      
      





コントローラをテストするための一般的なコードは、 抽象クラスにすることができます。

Spring MVCテストへのセキュリティの接続が少し簡単になりました。

  mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext) .apply(springSecurity()).build();
      
      





RESTサービスの場合、プロジェクトはhttp-basicを使用します。http-basic のSpring Security Testでのサポートは、他にも数多くあります。

便宜上、 テストデータを作成し、httpBasic接続をさらに簡単にします。

 public static RequestPostProcessor userHttpBasic(User user) { return SecurityMockMvcRequestPostProcessors .httpBasic(user.getEmail(), user.getPassword()); } mockMvc.perform(get(REST_URL).contentType(MediaType.APPLICATION_JSON) .with(userHttpBasic(ADMIN))) .andExpect(...
      
      





同時に、テストでセキュリティコンテキストは変更されていませんが、 実行する必要がありましたが、httpBasicの "Authorization"ヘッダーは正直に設定されています。



独自のResultMatcherを介した応答のJSONコンテンツの確認



すべてのRESTテストガイドの一般的なプラクティス: json-pathを使用して、json応答のコンテンツのフィールドを選択的にチェックします(通常、完全なチェックには十分な忍耐がありません)。 または、 より高度なライブラリを使用しても、アプローチの本質は変わりません。



ただし、オブジェクト全体をネストされたすべての階層レベルとすぐに比較することをお勧めします! なぜなら JSONオブジェクトの文字列表現を比較することはできません(フォーマットとフィールドの順序が異なる場合があります)。JSON応答のコンテンツをオブジェクトにシリアル化し、オブジェクトを比較する必要があります。 Spring MVCはJackson JSONライブラリと統合されているため、 ObjectMapperを好きなように構成し (たとえば、 Hibernateオブジェクトフィールドの遅延読み込みのシリアル化を無効にし)、 JSONシリアル化/逆シリアル化の便利なユーティリティクラスを作成できます。



Spring Test構文テストで使用する場合:

 .andExpect(status().isOk()) .andExpect(content().contentType(MediaType.APPLICATION_JSON))
      
      





オブジェクトとオブジェクトのリストをそれぞれ比較するメソッドcontentMatchercontentListMatcherで 独自のResultMatcherを作成します 。 必要なオブジェクトと連携するようにこのMatcherを構成するだけで十分です(最も単純な場合、ORMオブジェクトのequalsメソッドがPKの等価性に従って作成され、比較に使用できない場合、 toStringを介してオブジェクトを比較できます ):

 public static final ModelMatcher<UserMeal, String> MATCHER = new ToStringModelMatcher<>(UserMeal.class);
      
      





より複雑なケースでは、比較のためにORMオブジェクトのラッパー作成する必要があります

しかし、今では、JSONオブジェクトの任意のレベルの添付ファイルを使用して、REST応答のJSONオブジェクトをチェックするテストは非常に簡単になります。



 mockMvc.perform(get(REST_URL + "by?email=" + USER.getEmail()) .with(userHttpBasic(ADMIN))) .andExpect(MATCHER.contentMatcher(USER)) .andExpect(...
      
      





プロジェクトコントローラのRESTテストは、メモリ内のhsqldbで構成されているため、DBに接続せずに実行できます。

これらの解決策が役立つことを願っており、ご清聴ありがとうございました。



All Articles