JUnit 5でのテストクラス作成

GMOアドマーケティングのT.Nです。
弊社のプロジェクトのJUnitを、JUnit 5にアップグレードしたので、
今回はJUnit 5について書きます。

JUnit 5とは

JUnit 5 User Guideには以下のように記載されています。

JUnit 5 = JUnit Platform + JUnit Jupiter + JUnit Vintage

引用元: JUnit 5 User Guide

それぞれを簡単に説明すると、以下のようになります。

JUnit Platform テスト実行のためのプラットフォームなどの部分
JUnit Jupiter JUnit 5のテストを書くためのAPIやテストエンジン
JUnit Vintage JUnit3、JUnit 4のテストエンジン

JUnit 4では、全ての機能が1つのパッケージに入っていましたが、
JUnit 5からは分割されました。

JUnit 5では、必要に応じてJARファイルを依存関係に含める必要があります。
JUnit 4で書かれたテストを実行する場合は、junit-vintage-engineが必要になります。
現時点では、experimentalの機能も別のパッケージで提供されています。

JUnit 5を使用したテスト

JUnit 5の特徴を活かしたテストを紹介します。
今回は、JSONなどをオブジェクトに変換する、Jacksonのテストクラスを部分的に作成しました。

JacksonのGitHubページ

テストでは、ObjectMapperTesterというインターフェースに記述した内容が、
JSON、YAML、XMLの場合でそれぞれ実行されるようになっています。

テストクラス

ObjectMapperTest.java

テストで使用したEmployeeクラス

Employee.java

テストで使用したデータ

employee.json

employee.yaml

employee.xml

テストクラスの解説

上記のテストクラスでは、JUnit 5の以下のような特徴を取り入れています。

Test Interfaces and Default Methods

インターフェースに@Testなどをつけたdefaultメソッドを定義することで、
インターフェースを実装したクラスで、テストを実行することができます。

先ほどのテストクラスでは、
変換前のデータ形式ごとに内部クラスを作成し、インターフェースを実装しています。
それぞれの内部クラスでは、インターフェースに定義された、
データ形式ごとのObjectMapperを取得するメソッドや、
expectedの値を取得するメソッドなどをオーバーライドしています。

インターフェースにテストを記述することで、
テストを共通化できるので、テストコードの量を減らすことができます。

また、defaultメソッドに、
@BeforeAll、@BeforeEach、@AfterAll、@AfterEachなどのアノテーションをつけることで、
インターフェースを実装したクラスでの前処理、後処理を定義することもできます。

Dynamic Tests

JUnit 5ではテストを動的に実行することができます。
Dynamic Testは、@TestFactoryをつけた、Streamを返すメソッドによって定義することができます。
テストデータを動的に生成する場合などに活用できそうです。

先ほどのテストクラスでは、Dynamic Testのメリットを十分に活かせていないかもしれませんが、
JUnit 5を使ったテストクラスでは、活用する機会も多くなると思います。

Nested Tests

JUnit 5ではテストをネストさせることができます。
@Nestedをつけた内部クラスによって定義することができます。

先ほどのテストクラスでも、
テストケースごとに内部クラスを定義し、テストケースが明確になるようにしました。

ケースごとにネストさせることで、
テストの内容が分かりやすいテストクラスを作成できると思います。

Display Names

@DisplayNameを使用して、テストクラスに説明を記述できます。
記述した内容が、テスト実行時に表示されます。

JUnit 5以前では、メソッド名にテストの説明が日本語で書かれることもあったと思いますが、
JUnit 5では、メソッド名は英語のままで、@DisplayNameにテストの説明を書くと良さそうです。

最後に

今回紹介したJUnit 5の機能は一部です。
他の機能にも興味をお持ちの方は、JUnit 5 User Guideをご覧になってください。

JUnit 5 User Guide

User Guideにはテストコードのサンプルがいくつか載っていますが、
どれもJUnit 5の特徴を簡単に説明するためのコードであったため、
今回のブログでは、より業務で使用するものに近そうなサンプルを載せてみました。

弊社でもJUnit 5にバージョンアップしたばかりなので、
どのようにJUnit 5でテストクラスを書くと良いかを模索している状況です。
まだ活用できていない機能もあると思いますが、
今後もJUnit 5を活用して、読みやすいテストクラスを作成していきたいです。