ユニットテスト

依存性注入により、コードは従来の J2EE/Java EE 開発よりもコンテナーへの依存度が低くなります。アプリケーションを構成する POJO は、Spring またはその他のコンテナーを使用せずに、new オペレーターを使用してインスタンス化されたオブジェクトを使用して、JUnit または TestNG テストでテスト可能である必要があります。モックオブジェクトを(他の貴重なテスト手法と組み合わせて)使用して、コードを分離してテストできます。Spring のアーキテクチャの推奨事項に従うと、コードベースのクリーンな階層化とコンポーネント化により、単体テストが容易になります。例: 単体テストの実行中に永続データにアクセスする必要なしに、DAO またはリポジトリインターフェースをスタブまたはモックすることでサービスレイヤーオブジェクトをテストできます。

通常、設定するランタイムインフラストラクチャがないため、真のユニットテストは非常に迅速に実行されます。開発方法論の一部として真の単体テストを強調すると、生産性を高めることができます。IoC ベースのアプリケーションの効果的な単体テストを作成するために、テストの章のこのセクションは必要ない場合があります。ただし、特定のユニットテストシナリオでは、Spring Framework はモックオブジェクトとテストサポートクラスを提供します。これらについては、この章で説明します。

モックオブジェクト

Spring には、モック専用のパッケージがいくつか含まれています。

環境

org.springframework.mock.env パッケージには、Environment および PropertySource 抽象化のモック実装が含まれています(Bean 定義プロファイルおよび PropertySource の抽象化を参照)。MockEnvironment および MockPropertySource は、環境固有のプロパティに依存するコードのコンテナー外テストの開発に役立ちます。

サーブレット API

org.springframework.mock.web パッケージには、Web コンテキスト、コントローラー、フィルターのテストに役立つサーブレット API モックオブジェクトの包括的なセットが含まれています。これらのモックオブジェクトは、Spring の Web MVC フレームワークでの使用を対象としており、一般に動的なモックオブジェクト(EasyMock (英語) など)や代替の Servlet API モックオブジェクト(MockObjects (英語) など)よりも使いやすいです。

Spring Framework 6.0 以降、org.springframework.mock.web のモックオブジェクトは Servlet 6.0 API に基づいています。

MockMvc は、モックサーブレット API オブジェクトに基づいて構築され、Spring MVC の統合テストフレームワークを提供します。MockMvc を参照してください。

Spring Web リアクティブ

org.springframework.mock.http.server.reactive パッケージには、WebFlux アプリケーションで使用するための ServerHttpRequest および ServerHttpResponse のモック実装が含まれています。org.springframework.mock.web.server パッケージには、これらのモックリクエストおよびレスポンスオブジェクトに依存するモック ServerWebExchange が含まれています。

MockServerHttpRequest と MockServerHttpResponse は両方とも、サーバー固有の実装と同じ抽象基本クラスから拡張され、それらと動作を共有します。例: 作成されたモックリクエストは不変ですが、ServerHttpRequest の mutate() メソッドを使用して、変更されたインスタンスを作成できます。

モックレスポンスが書き込み契約を適切に実装し、書き込み完了ハンドル(つまり、Mono<Void>)を返すために、デフォルトで Flux と cache().then() を使用します。これにより、データがバッファリングされ、テストでのアサーションに使用できるようになります。アプリケーションは、カスタム書き込み機能を設定できます(たとえば、無限ストリームをテストするため)。

WebTestClient は、モックのリクエストとレスポンスに基づいて構築され、HTTP サーバーなしで WebFlux アプリケーションのテストをサポートします。クライアントは、実行中のサーバーでのエンドツーエンドテストにも使用できます。

単体テストのサポートクラス

Spring には、単体テストに役立つ多くのクラスが含まれています。それらは 2 つのカテゴリに分類されます。

一般的なテストユーティリティ

org.springframework.test.util パッケージには、単体テストおよび統合テストで使用するためのいくつかの汎用ユーティリティが含まれています。

AopTestUtils (Javadoc) は、AOP 関連のユーティリティメソッドのコレクションです。これらのメソッドを使用して、1 つ以上の Spring プロキシの背後に隠されている基礎となるターゲットオブジェクトへの参照を取得できます。例: EasyMock や Mockito などのライブラリを使用して Bean を動的なモックとして構成しており、モックが Spring プロキシにラップされている場合、基礎となるモックに直接アクセスして、そのモックに期待を構成し、検証を実行する必要がある場合があります。Spring のコア AOP ユーティリティについては、AopUtils (Javadoc) および AopProxyUtils (Javadoc) を参照してください。

ReflectionTestUtils (Javadoc) は、リフレクションベースのユーティリティメソッドのコレクションです。これらのメソッドは、アプリケーションコードをテストするときに、定数の値の変更、非 public フィールドの設定、非 public setter メソッドの呼び出し、または非 public 構成またはライフサイクルコールバックメソッドの呼び出しが必要なテストシナリオで使用できます。次のような使用例:

  • ドメインエンティティのプロパティの public setter メソッドではなく、private または protected フィールドアクセスを許可する ORM フレームワーク(JPA や Hibernate など)。

  • private または protected フィールド、setter メソッド、構成メソッドの依存性注入を提供する、アノテーション(@Autowired@Inject@Resource など)に対する Spring のサポート。

  • ライフサイクルコールバックメソッドに対する @PostConstruct や @PreDestroy などのアノテーションの使用。

TestSocketUtils (Javadoc) は、統合テストシナリオで使用するために、localhost で利用可能な TCP ポートを見つけるためのシンプルなユーティリティです。

TestSocketUtils は、使用可能なランダムポートで外部サーバーを起動する統合テストで使用できます。ただし、これらのユーティリティは、指定されたポートのその後の可用性について保証しないため、信頼できません。TestSocketUtils を使用してサーバーの使用可能なローカルポートを見つける代わりに、オペレーティングシステムによって選択または割り当てられたランダムな一時ポートで起動するサーバーの機能に依存することをお勧めします。そのサーバーと対話するには、サーバーが現在使用しているポートをサーバーに照会する必要があります。

Spring MVC テストユーティリティ

org.springframework.test.web パッケージには ModelAndViewAssert (Javadoc) が含まれています。これは、JUnit、TestNG、Spring MVC ModelAndView オブジェクトを処理する単体テスト用の他のテストフレームワークと組み合わせて使用できます。

Spring MVC コントローラーの単体テスト
Spring MVC Controller クラスを POJO として単体テストするには、ModelAndViewAssert を Spring のサーブレット API モックから MockHttpServletRequestMockHttpSession などと組み合わせて使用します。Spring MVC および REST Controller クラスの完全な統合テストを Spring MVC の WebApplicationContext 構成と組み合わせて行うには、代わりに MockMvc を使用してください。