MockMvc とエンドツーエンドのテスト

MockMvc は、spring-test モジュールの Servlet API モック実装に基づいて構築されており、実行中のコンテナーに依存しません。そのため、実際のクライアントとライブサーバーが稼働している完全なエンドツーエンドの統合テストと比較すると、いくつかの違いがあります。

これについて考える最も簡単な方法は、空の MockHttpServletRequest から始めることです。これに追加する内容が、リクエストの内容になります。驚くかもしれませんが、デフォルトではコンテキストパスが存在せず、jsessionid クッキーも転送、エラー、非同期ディスパッチも存在せず、実際の JSP レンダリングも行われません。代わりに、「転送」および「リダイレクト」された URL が MockHttpServletResponse に保存され、期待値を使用してアサートできます。

つまり、JSP を使用する場合、リクエストが転送された JSP ページを確認できますが、HTML はレンダリングされません。つまり、JSP は呼び出されません。ただし、Thymeleaf や Freemarker など、転送に依存しない他のすべてのレンダリングテクノロジでは、期待どおりに HTML がレスポンス本文にレンダリングされることに注意してください。@ResponseBody メソッドを使用して JSON、XML、その他の形式をレンダリングする場合も同様です。

または、Spring Boot と @SpringBootTest の完全なエンドツーエンド統合テストのサポートを検討することもできます。Spring Boot リファレンスガイドを参照してください。

それぞれのアプローチには長所と短所があります。Spring MVC テストで提供されるオプションは、従来の単体テストから完全な統合テストまで、さまざまな段階に分かれています。確かに、Spring MVC テストのオプションはどれも従来の単体テストの範疇には入りませんが、それに少し近いものです。例: モックサービスをコントローラーに挿入することで Web レイヤーを分離できます。その場合、データアクセスレイヤーをその上のレイヤーから分離してテストするため、Web レイヤーは DispatcherServlet のみでテストされますが、実際の Spring 構成が使用されます。また、スタンドアロンセットアップを使用して、一度に 1 つのコントローラーに焦点を絞り、コントローラーを動作させるために必要な構成を手動で提供することもできます。

Spring MVC テストを使用する場合のもう 1 つの重要な違いは、概念的には、このようなテストはサーバー側のテストであるため、どのハンドラーが使用されたか、例外が HandlerExceptionResolver で処理されたかどうか、モデルの内容は何か、どのようなバインディングエラーがあったか、およびその他の詳細を確認できることです。つまり、サーバーは実際の HTTP クライアントを介してテストする場合のように不透明なボックスではないため、期待値を記述するのが簡単になります。これは一般に、従来の単体テストの利点です。記述、推論、デバッグが簡単ですが、完全な統合テストの必要性を置き換えるものではありません。同時に、レスポンスが最も重要であるという事実を見失わないことが重要です。つまり、同じプロジェクト内であっても、複数のスタイルと戦略のテストを行う余地があります。