ファイルを利用したテストを行う際に、ファイルのクリーンアップを行うのは面倒な作業です。 インメモリでファイルシステムを模倣するJimfs を利用することも出来ますが、JUnit 5 では JUnit 4 では、以下のように JUnit 5 では、 JUnit 5 における一時ディレクトリサポートは、JUnit 5.4 で EXPERIMENTAL(実験的)機能として追加され、JUnit 5.10 にて STABLE(安定版) になりました。 JUnit 5 における一時ディレクトリサポートは、拡張機能として提供されていますが、デフォルトでこの拡張機能が組み込まれているため、 メソッドパラメータに 以下のように複数の一時ディレクトリを扱うこともできます。 テストクラスのインスタンスフィールドで一時ディレクトリを定義することもできます。この場合でも、複数のテストメソッドでは、それぞれ別の一時ディレクトリとなります( すべてのテストメソッドで同じ一時ディレクトリを使う場合は、 一時ディレクトリは、テスト完了時にクリーンアップされます。 この挙動は、 指定しない場合は、 一時ディレクトリの生成は デフォルトでは、以下のような つまり、Java の この挙動は、 指定するファクトリは、 この例では、一時ディレクトリのプレフィックスにテスト名を付与したものです。 JUnit 5.10 で安定版となった はじめに
@TempDir
により、この作業を軽減できます。JUnit 5 における一時ディレクトリサポート
@Rule
で TemporaryFolder
を使っていました。 public static class HasTempFolder {
@Rule
public TemporaryFolder folder= new TemporaryFolder();
@Test
public void testUsingTempFolder() throws IOException {
File createdFile= folder.newFile("myfile.txt");
// ...
}
}
@TempDir
アノテーションにより以下のように一時ディレクトリを利用できます。@Test
void writeItemsToFile(@TempDir Path tempDir) throws IOException {
Path file = tempDir.resolve("test.txt");
// ...
}
@TempDir
support for temporary directories@API(status = EXPERIMENTAL, since = "5.4")
@TempDir
can be used to create multiple temporary directories
@TempDir
TempDirFactory
SPI for customizing how temporary directories are created@API(status = STABLE, since = "5.10")
@ExtendWith
による登録作業は不要です。@TempDir の使い方
@TempDir
を付けることで、一時ディレクトリを得ることができ、この一時ディレクトリは、テスト終了時に破棄されます。@Test void writeItemsToFile(@TempDir Path tempDir) throws Exception {
var file = tempDir.resolve("test.txt");
var lines = List.of("a", "b");
Files.write(file, lines);
assertLinesMatch(lines, Files.readAllLines(file));
}
@TempDir
は、java.nio.file.Path
または java.io.File
に付与することができます。@Test void writeItemsToFile(@TempDir Path tempDir1,
@TempDir Path tempDir2) throws Exception {
}
@BeforeAll
や @BeforeEach
などのライフサイクルメソッドで初期設定を行い、テストメソッドで利用することができます)。class SharedTempDirectory {
@TempDir Path tempDir;
}
static
フィールドに @TempDir
でアノテートします。class SharedTempDirectory {
@TempDir static Path sharedTempDir;
@Test void test1() throws Exception { }
@Test void test2() throws Exception { }
}
一時ディレクトリのクリーンアップ
@TempDir
アノテーションの cleanup
属性で変更できます(5.10 の段階では未だ EXPERIMENTAL
)。@Test
void fileTest(@TempDir(cleanup = ON_SUCCESS) Path tempDir) {
// ...
}
cleanup
属性は以下があります。public enum CleanupMode {
DEFAULT, // junit.jupiter.tempdir.cleanup.mode.default の定義を利用
ALWAYS, // 常にクリーンアップ
ON_SUCCESS,// テスト成功時にクリーンアップ
NEVER; // クリーンアップなし
}
CleanupMode.DEFAULT
となり、junit.jupiter.tempdir.cleanup.mode.default
で定義されたクリーンアップモードを使うようになっています(この設定は、CleanupMode.ALWAYS
が設定されています)。一時ディレクトリ生成のカスタマイズ
TempDirFactory
を介して行われます。public interface TempDirFactory extends Closeable {
Path createTempDirectory(AnnotatedElementContext elementContext,
ExtensionContext extensionContext) throws Exception;
@Override
default void close() throws IOException {
}
TempDirFactory.Standard
により一時ディレクトリが作成されます。class Standard implements TempDirFactory {
public static final TempDirFactory INSTANCE = new Standard();
private static final String TEMP_DIR_PREFIX = "junit";
@Override
public Path createTempDirectory(AnnotatedElementContext elementContext,
ExtensionContext extensionContext) throws IOException {
return Files.createTempDirectory(TEMP_DIR_PREFIX);
}
}
java.io.tmpdir
プロパティのディレクトリ内に、junit
というプレフィックス付きで一時ディレクトリが作成されます。@TempDir
アノテーションの factory
属性にファクトリを指定することで変更できます(5.10 の段階では未だ EXPERIMENTAL
)(設定 junit.jupiter.tempdir.factory.default
により設定することも可能)。@Test void fileTest(@TempDir(factory = MyFactory.class) Path tempDir) {
// ...
}
TempDirFactory
を実装して以下のように実装できます。static class MyFactory implements TempDirFactory {
@Override
public Path createTempDirectory(AnnotatedElementContext elementContext,
ExtensionContext extensionContext) throws IOException {
return Files.createTempDirectory(
extensionContext.getRequiredTestMethod().getName());
}
}
まとめ
@TempDir
による一時ディレクトリサポートについて説明しました。
@TempDir
を付けることで、一時ディレクトリを得る@TempDir
の cleanup
属性で、一時ディレクトリのクリーンアップの振る舞いをカスタマイズ@TempDir
の factory
属性で、一時ディレクトリの生成をカスタマイズ