JUnit 5测试中的临时目录(附实例及代码)

在JUnit 5.4中引入了一个新的内置扩展,用于处理测试过程中的临时目录。本文通过实例展示了如何使用`@TempDir`注解在测试方法的参数、实例字段中创建和管理临时目录,并讨论了共享临时目录的情况。总结了利用`@TempDir`在测试中处理临时目录的便利性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

JUnit 4 TemporaryFolder @Rule 允许开发人员利用临时目录来创建测试。在JUnit 5中,不支持 @Rule s,因此测试文件和目录需要一点额外的工作。幸运的是,在JUnit 5.4中,有一个新的内置扩展来处理测试中的临时目录,而且它非常容易使用:

你还在用JUnit 4工作吗?请看我以前的文章: 在JUnit 4中用TemporaryFolder @Rule测试文件和目录 。

@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 ,你可以在测试中轻松地处理临时目录。这里没有魔法:你注解 Path 或 File 对象,并在你需要时注入。其余的由JUnit为你处理。

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

参见

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值