JUnit 4TemporaryFolder @Rule 答应开发人员利用暂时目录来创立测验。在JUnit 5中,不支持@Rules,因而测验文件和目录需要一点额外的作业。走运的是,在JUnit 5.4中,有一个新的内置扩展来处理测验中的暂时目录,并且它十分简略运用:

@TempDir

@org.junit.jupiter.api.io.TempDir 注解能够用来注解类字段或生命周期中的参数(例如: )或测验办法的类型 或 。一旦这样做了,暂时目录就会被创立。一旦测验办法或类履行完毕,该目录及其在测验履行过程中创立的内容将被删去。@BeforeEach File Path

要测验的代码

在这个简略的比如中,咱们将测验FileWriter 类,它有一个单一的办法将文本内容写入一个新文件:


public class FileWriter {
    public void writeTo(String path, String content) throws IOException {
        Path target = Paths.get(path);
        if (Files.exists(target)) {
            throw new IOException("file already exists");
        }
        Files.copy(new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8)), target);
    }
}

@TempDir 作为测验办法的参数

在这个比如中,咱们将用@TempDir 注释来测验参数:

import org.junit.jupiter.api.io.TempDir;
@Test
void writesContentToFile(@TempDir Path tempDir) throws IOException {
    // arrange
    Path output = tempDir
            .resolve("output.txt");
    // act
    fileWriter.writeTo(output.toString(), "test");
    // assert
    assertAll(
            () -> assertTrue(Files.exists(output)),
            () -> assertLinesMatch(List.of("test"), Files.readAllLines(output))
    );
}

@TempDir 作为一个实例字段

import org.junit.jupiter.api.io.TempDir;
class FileWriterTest {
    private FileWriter fileWriter = new FileWriter();
    @TempDir
    Path tempDir;
    @BeforeEach
    void beforeEach() {
        assertTrue(Files.isDirectory(this.tempDir));
    }
    @RepeatedTest(3)
    void throwsErrorWhenTargetFileExists() throws IOException {
        // arrange
        Path output = Files.createFile(
                tempDir.resolve("output.txt")
        );
        // act & assert
        IOException expectedException = assertThrows(IOException.class, () -> fileWriter.writeTo(output.toString(), "test"));
        assertEquals("file already exists", expectedException.getMessage());
    }
}

依据上述比如,咱们能够看到,每次重复测验都会运用一个新的暂时目录(依据规范测验类的生命周期),因而办法的安排部分履行起来没有任何错误。

同享@TempDir

假如需要在测验办法之间同享一个暂时目录,咱们能够创立一个静态字段并重复运用暂时目录,如下面的比如:

import org.junit.jupiter.api.io.TempDir;
class FileWriterTest {
    private FileWriter fileWriter = new FileWriter();
    @TempDir
    static Path tempDir;
    @BeforeAll
    static void setUp() {
        assertTrue(Files.isDirectory(tempDir));
    }
    @RepeatedTest(3)
    void throwsErrorWhenTargetFileExists(RepetitionInfo repetitionInfo) throws IOException {
        // arrange
        Path output = Files.createFile(
                tempDir.resolve(repetitionInfo.getCurrentRepetition() + "_output.txt")
        );
        // act & assert
        IOException expectedException = assertThrows(IOException.class, () -> fileWriter.writeTo(output.toString(), "test"));
        assertEquals("file already exists", expectedException.getMessage());
    }
}

请注意,测验办法的安排部分在每次履行时创立仅有的文件名(运用当前的重复计数器),否则FileAlreadyExistsException

总结

经过@TempDir ,你能够在测验中轻松地处理暂时目录。这儿没有魔法:你注解PathFile 对象,并在你需要时注入。其余的由JUnit为你处理。

在GitHub上找到这些比如:https://github.com/kolorobot/junit5-samples/tree/master/junit5-built-in-extensions

参见

  • JUnit 5中的测验履行顺序
  • 用JUnit 5进行更洁净的参数化测验
  • JUnit 5遇到AssertJ