JUnit 5の一時ディレクトリのサポート

1. 概要

テスト時には、多くの場合、一時ファイルにアクセスする必要があります。 ただし、これらのファイルの作成と削除を自分で管理するのは面倒です。
このクイックチュートリアルでは、* TempDirectory拡張機能を提供することでJUnit 5がこれをどのように軽減するかを見ていきます*。
JUnitを使用したテストの詳細なガイドについては、https://www.baeldung.com/junit-5 [JUnit 5のガイド]をご覧ください。

2. TempDirectory拡張機能

バージョン5.4.2以降、JUnit 5はTempDirectory拡張機能を提供します。 ただし、公式にこれはまだhttps://apiguardian-team.github.io/apiguardian/docs/1.0.0/api/org/apiguardian/api/API.Status.html?is-external=であることに注意することが重要ですtrue#EXPERIMENTAL [experimental]機能。JUnitチームにフィードバックすることをお勧めします。
後で見るように、この拡張機能を使用して、個々のテストまたはテストクラス内のすべてのテスト用の一時ディレクトリを作成およびクリーンアップできます*。
通常、https://www.baeldung.com/junit-5-extensions [拡張機能を使用]の場合、_ @ ExtendWith_アノテーションを使用してJUnit 5テスト内から登録する必要があります。 ただし、組み込みでデフォルトで登録されているTempDirectory拡張機能では、これは不要です。

3. Mavenの依存関係

まず、例に必要なプロジェクトの依存関係を追加しましょう。
メインのJUnit 5ライブラリ_junit-jupiter-engine_の他に、_junit-jupiter-api_ライブラリも必要です。
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-api</artifactId>
    <version>5.4.2</version>
    <scope>test</scope>
</dependency>
いつものように、最新バージョンはhttps://search.maven.org/classic/#search%7Cga%7C1%7Ca%3A%22junit-jupiter-api%22[Maven Central]から入手できます。
これに加えて、_junit-jupiter-params_依存関係も追加する必要があります。
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-params</artifactId>
    <version>5.4.2</version>
    <scope>test</scope>
</dependency>
繰り返しますが、最新バージョンはhttps://search.maven.org/classic/#search%7Cga%7C1%7Ca%3A%22junit-jupiter-params%22[Maven Central]で見つけることができます。

4. _ @ TempDir_アノテーションの使用

TempDirectory拡張機能を使用するには、* _ @ TempDir_アノテーションを使用する必要があります*。 この注釈は、次の2つのタイプでのみ使用できます。
  • java.nio.file.Path

  • java.io.File

    実際、別のタイプで使用しようとすると、_org.junit.jupiter.api.extension.ParameterResolutionException_がスローされます。
    次に、このアノテーションを使用するいくつかの異なる方法を探りましょう。

* 4.1。 メソッドパラメーターとしての_ @ TempDir_ *

まず、_ @ TempDir_アノテーションが付けられたパラメーターを単一のテストメソッドに挿入する方法を見てみましょう*:
@Test
void givenTestMethodWithTempDirectory_whenWriteToFile_thenContentIsCorrect(@TempDir Path tempDir)
  throws IOException {
    Path numbers = tempDir.resolve("numbers.txt");

    List<String> lines = Arrays.asList("1", "2", "3");
    Files.write(numbers, lines);

    assertAll(
      () -> assertTrue("File should exist", Files.exists(numbers)),
      () -> assertLinesMatch(lines, Files.readAllLines(numbers)));
}
ご覧のとおり、このテストメソッドは、_numbers.txt_というファイルを作成し、一時ディレクトリ_tempDir_に書き込みます。
次に、ファイルが存在し、コンテンツが最初に書き込まれたものと一致することを確認します。 本当に素敵でシンプル!

* 4.2。 インスタンスフィールドの_ @ TempDir_ *

次の例では、_ @ TempDir_注釈を使用してテストクラスのフィールドに注釈を付けます。
@TempDir
File anotherTempDir;

@Test
void givenFieldWithTempDirectoryFile_whenWriteToFile_thenContentIsCorrect() throws IOException {
    assertTrue("Should be a directory ", this.anotherTempDir.isDirectory());

    File letters = new File(anotherTempDir, "letters.txt");
    List<String> lines = Arrays.asList("x", "y", "z");

    Files.write(letters.toPath(), lines);

    assertAll(
      () -> assertTrue("File should exist", Files.exists(letters.toPath())),
      () -> assertLinesMatch(lines, Files.readAllLines(letters.toPath())));
}
今回は、一時ディレクトリにjava.io.Fileを使用します。 繰り返しますが、いくつかの行を書き、それらが正常に書き込まれたことを確認します。
*この単一の参照を他のテストメソッドで再度使用する場合、各テストは独自の一時ディレクトリを使用します*。

* 4.3。 共有一時ディレクトリ*

場合によっては、*テストメソッド間で一時ディレクトリを共有したい場合があります*。
これを行うには、フィールド_static_を宣言します。
@TempDir
static Path sharedTempDir;

@Test
@Order(1)
void givenFieldWithSharedTempDirectoryPath_whenWriteToFile_thenContentIsCorrect() throws IOException {
    Path numbers = sharedTempDir.resolve("numbers.txt");

    List<String> lines = Arrays.asList("1", "2", "3");
    Files.write(numbers, lines);

    assertAll(
        () -> assertTrue("File should exist", Files.exists(numbers)),
        () -> assertLinesMatch(lines, Files.readAllLines(numbers)));
}

@Test
@Order(2)
void givenAlreadyWrittenToSharedFile_whenCheckContents_thenContentIsCorrect() throws IOException {
    Path numbers = sharedTempDir.resolve("numbers.txt");

    assertLinesMatch(Arrays.asList("1", "2", "3"), Files.readAllLines(numbers));
  }
*ここで重要なのは、2つのテストメソッド間で共有する静的フィールド_sharedTempDir_を使用することです*。
最初のテストでは、_numbers.txt_というファイルに再びいくつかの行を書き込みます。 次に、次のテストでファイルとコンテンツが既に存在することを確認します。
また、動作が常に一貫していることを確認するために、_ @ Order_アノテーションを介してlink:/junit-5-test-order [テストの順序]を強制します。

5. 落とし穴

次に、TempDirectory拡張機能を使用する際に注意すべき微妙な点をいくつか見てみましょう。

* 5.1。 作成*

好奇心reader盛な読者は、おそらくこれらの一時ファイルが実際にどこで作成されているのか疑問に思うでしょう。
まあ、内部的にはJUnit _TemporaryDirectory_クラスは_Files.createTempDirectory(String prefix)_メソッドを利用します。 *同様に、このメソッドはデフォルトのシステム一時ファイルディレクトリを使用します*。
これは通常、環境変数_TMPDIR_で指定されます。
TMPDIR=/var/folders/3b/rp7016xn6fz9g0yf5_nj71m00000gn/T/
たとえば、一時ファイルの場所は次のようになります。
/var/folders/3b/rp7016xn6fz9g0yf5_nj71m00000gn/T/junit5416670701666180307/numbers.txt
一方、一時ディレクトリを作成できない場合、_ExtensionConfigurationException_が適切にスローされます。 または、前述のように、_ParameterResolutionException_。

* 5.2。 削除*

テストメソッドまたはクラスの実行が終了し、一時ディレクトリが範囲外になると、* JUnitフレームワークは、そのディレクトリ内のすべてのファイルとディレクトリ、最後に一時ディレクトリ自体を再帰的に削除しようとします。*
この削除段階で問題が発生すると、_IOException_がスローされ、テストまたはテストクラスが失敗します。

6. 結論

要約すると、このチュートリアルでは、JUnit 5が提供するTempDirectory拡張機能について説明しました。
最初に、拡張機能を導入することから始め、それを使用するために必要なMaven依存関係を学習しました。 次に、単体テスト内から拡張機能を使用する方法の例をいくつか見てきました。
最後に、一時ファイルの作成場所や削除中の処理など、いくつかの落とし穴を調べました。
いつものように、記事の完全なソースコードはhttps://github.com/eugenp/tutorials/tree/master/testing-modules/junit-5-basics[GitHubで]から入手できます。