これは、なにをしたくて書いたもの?
Springに関するテストの話について、あまり知らないのでちょっと見ておこうかな、と思いまして。
さらっと、Springのテストに関するドキュメントを眺めてみます。
Springのテストに関する話
今回扱うのは、Spring Bootのテストに関する話とSpring Frameworkのテストに関する話(Spring Test)について見ていこうかなと思います。
対象のバージョンは、以下とします。
- Spring Boot 2.6.6
- Spring Framework 5.3.18
Spring Bootのテストに関するドキュメントはこちら。
Spring Frameworkのテスト(Spring Test)に関するドキュメントは、こちら。
それぞれ見ていきますが、今回は単体テストについて
Spring Bootとテスト
まずは、Spring Bootに関するテストについて、見ていきます。
こちらのドキュメントは、4つのセクションに分かれています。
- Core Features / Testing / Test Scope Dependencies
- テストのスコープに含まれるライブラリ
- JUnit 5、Spring Test、Spring Boot Test、AssertJ、Hamcrest、Mockito、JSONassert、JsonPath
- テストのスコープに含まれるライブラリ
- Core Features / Testing / Testing Spring Applications
- Springアプリケーションのテスト
- Core Features / Testing / Testing Spring Boot Applications
- Spring Bootアプリケーションのテスト
- Core Features / Testing / Test Utilities
- テストに関するユーティリティ
注目して読むべきは、Springアプリケーションのテストに関する話と、Spring Bootアプリケーションに関するテストの話ですね。
ところで、Test Scope DependenciesのSpring Testの箇所には、以下のように書かれています。
Spring Test & Spring Boot Test: Utilities and integration test support for Spring Boot applications.
テストのユーティリティと、Spring Bootアプリケーションのインテグレーションテストをサポートするものだ、と書かれていますね。
また、 Core Features / Testing / Testing Spring Applications を見ると、以下のように書かれています。
One of the major advantages of dependency injection is that it should make your code easier to unit test. You can instantiate objects by using the new operator without even involving Spring. You can also use mock objects instead of real dependencies.
Springを使わず、new
演算子を使ったインスタンス化、そしてモックを利用して単体テストができるということが書かれています。
SpringのApplicationContext
やSpring Test、Spring Boot Testを使うのはインテグレーションテストであるとも書かれています。
Often, you need to move beyond unit testing and start integration testing (with a Spring ApplicationContext).
The Spring Framework includes a dedicated test module for such integration testing. You can declare a dependency directly to org.springframework:spring-test or use the spring-boot-starter-test “Starter” to pull it in transitively.
つまり、Springのテストに関する機能は、インテグレーションテストを対象にしていることになります。
Spring Frameworkとテスト
ここで、Spring Frameworkのテストに関するドキュメントを見てみます。
このドキュメントは、主に次の2つの内容で構成されています。
ドキュメントの冒頭を見ると、このページは単体テストのベストプラクティスとSpringのインテグレーションテストに関するサポートに
ついて書いてある、との記載があります。
This chapter covers Spring’s support for integration testing and best practices for unit testing.
ここでも、Spring Frameworkの提供する機能の多くはインテグレーションテスト向けのものだということになりますね。
Spring Frameworkと単体テスト
Spring Frameworkのテストに関する話題はインテグレーションテストに関するものだということはわかりましたが、単体テストのセクションも
ありましたね。こちらも追ってみましょう。
このセクションの冒頭を見ると、以下のようなことが書かれています。
- POJOは、Springやその他のコンテナを使用せずに
new
演算子でインスタンス化し、JUnitなどでテストできるようにすべきだ - コードの分離は、モックを使って実現可能
- Springは、単体テスト向けのモックオブジェクトとテストサポートを提供する
基本的には単体テストはSpringを使わずに実行できるべきであり、ランタイムのセットアップが不要になるので単体テストは高速に
実行されることを期待しています。
True unit tests typically run extremely quickly, as there is no runtime infrastructure to set up. Emphasizing true unit tests as part of your development methodology can boost your productivity.
とはいえ、単体テスト向けのSpringのサポートもある、という話のようです。
提供されるのは、以下ですね。
- モックオブジェクト
- Environment
org.springframework.mock.env
パッケージに含まれるモック実装MockEnvironment
、MockPropertySource
- JNDI
org.springframework.mock.jndi
パッケージに含まれるモック実装- ただし非推奨化されており、Simple-JNDI等で代替される
- Servlet API
org.springframework.mock.web
パッケージに含まれるモック実装
- Spring Web Reactive
org.springframework.mock.http.server.reactive
パッケージに含まれるモック実装
- Environment
- 単体テストサポート
- General Testing Utilities
org.springframework.test.util
パッケージに含まれるユーティリティ- リフレクションのユーティリティ
ReflectionTestUtils
、AOP関連のユーティリティAopTestUtils
など
- Spring MVC Testing Utilities
- General Testing Utilities
Spring Frameworkとインテグレーションテスト
Spring Frameworkのテストに関するドキュメントには単体テストとインテグレーションテストの内容が書かれているわけですが、
ページ内のボリュームを見ると大半はインテグレーションテスト向けのものであることがわかります。
このセクションの概要を見てみます。
Testing / Integration Testing / Overview
It is important to be able to perform some integration testing without requiring deployment to your application server or connecting to other enterprise infrastructure.
アプリケーションサーバーへのデプロイや、他のエンタープライズインフラストラクチャーへの接続なしにインテグレーションテストを
実行できることを重要視しています。
これで、主にSpringのコンテキストを正しく構築できているか、データベースアクセスなどをテストできる、としています。
このセクションで書かれているSpring Test(spring-test
)のorg.springframework.test
パッケージには、Springのコンテナを使った
インテグレーションテストに関するクラスが含まれています。
これらを使用したテストはアプリケーションサーバーやその他の環境に依存しておらず、単体テストよりは遅いものの、アプリケーションサーバーに
デプロイしてのSeleniumでのテストやリモートテストよりもずっと高速です。
Springにおける、インテグレーションテストの目標は以下に書かれています。
Testing / Integration Testing / Goals of Integration Testing
こういった感じですね。
- テスト間のSpringコンテナのキャッシュ管理
- テストフィクスチャインスタンスのDIの提供
- 結合テストに適したトランザクション管理の提供
- 結合テストの作成を助けるための、Spring固有のベースクラスの提供
また、以下の機能が含まれています。
- Testing / Integration Testing / JDBC Testing Support
org.springframework.test.jdbc
パッケージに含まれるJDBC関連のユーティリティ
- Testing / Integration Testing / Annotations
- Spring TestContext Framework
org.springframework.test.context
パッケージに含まれ、テストにおけるSpringのコンテキストに関する機能を提供する
- WebTestClient
- サーバーアプリケーションをテストするために設計された、
WebClient
をラップしたWebTestClient
を提供する
- サーバーアプリケーションをテストするために設計された、
- MockMvc
- Testing Client Applications
- 内部的に
RestTemplate
を使用するスタブを使い、クライアント側でのテストをサポートする
- 内部的に
Spring Bootアプリケーションのテスト
ところで、Spring Bootのテストに関するセクションには、次の2つが含まれていました。
- Core Features / Testing / Testing Spring Applications
- Core Features / Testing / Testing Spring Boot Applications
Springアプリケーションのテストは、先ほどまで書いていたSpring Testの話です。
ではSpring Bootアプリケーションのテストに関する話は?というと、Spring BootアプリケーションもSpringアプリケーションであるため、
特別なことはないと書かれています。
A Spring Boot application is a Spring ApplicationContext, so nothing very special has to be done to test it beyond what you would normally do with a vanilla Spring context.
ですが、いくつかの機能は提供するようです。以下に一部を記載しますが、基本的にはAuto Configurationに関する機能のようですね。
- Detecting Web Application Type
- Detecting Test Configuration
- Spring Bootの
@*Test
アノテーションを使用することで、プライマリーの構成を明示しない場合は自動構成を行う
- Spring Bootの
- Testing with a mock environment
- モックサーバーでのテスト
- Testing with a running server
- 実際のサーバーを起動してのテスト
- Customizing WebTestClient
WebTestClient
のカスタマイズ
- Mocking and Spying Beans
- Beanのモックおよびスパイ
- Auto-configured Tests
- Spring BootのAuto Configurationをカスタマイズし、部分的にAuto Configurationを使うための多数のスライスおよびテスト
- 使い方は同セクションに書かれているが、別ページのTest Auto-configuration Annotationsに、各スライスに含まれるAuto Configurationが記載されている
- Test Utilities
- いくつかのテストユーティリティ(
ConfigDataApplicationContextInitializer
、TestPropertyValues
、OutputCapture
、TestRestTemplate
- いくつかのテストユーティリティ(
- Creating Your Own Auto-configuration
- 独自のAuto Configurationのサポート
まとめ
Springのテストに関するドキュメントを見て、Springのテストのサポートに対する考え方や、カバーするフェーズ(単体テスト、
インテグレーションテスト)、どのような機能が提供するかをざっくり眺めてみました。
雰囲気はおよそわかったので、そのうちいくつかの機能を使ってテストに関する勉強をしていきたいですね。