@tempdir 是 junit 5.4+ 提供的注解,用于自动创建并清理临时目录;推荐作为测试方法参数注入(如 @test void test(@tempdir path tempdir)),每个测试独享隔离目录,执行前后自动创建与删除,无需手动管理,兼容 ide、maven 和 ci 环境。

JUnit 5 中使用 @TempDir 是测试文件读写最安全、最推荐的方式——它自动创建隔离目录,测试结束自动清理,避免污染系统临时目录或残留文件。
直接用作测试方法参数(最简单可靠)
这是首选方式,无需额外配置,兼容所有运行环境(IDE、Maven、CI):
- 将
@TempDir Path tempDir声明为测试方法的参数,JUnit 会自动注入一个全新、空的临时目录路径 - 该目录在测试方法执行前创建,方法结束后由 JUnit 自动删除(包括所有子文件和子目录)
- 适合绝大多数场景,比如写入配置文件、生成日志、模拟上传临时文件等
示例:
@Test
void writeAndReadFile(@TempDir Path tempDir) throws IOException {
Path file = tempDir.resolve("data.txt");
Files.writeString(file, "hello world");
String content = Files.readString(file);
assertEquals("hello world", content);
}
作为类字段使用(需满足构建插件要求)
若想在多个测试方法间复用同一个临时目录(不推荐,易引发耦合),可声明为实例字段:
- 必须确保 Maven 的
maven-surefire-plugin显式配置且版本 ≥ 3.0.0(如 3.2.5) - 否则在
mvn test下会报NullPointerException,因为扩展未被激活 - IntelliJ 运行正常不代表 Maven 正常,务必验证 CI 环境
正确写法:
@TempDir
Path tempDir; // 字段级注入
@Test
void firstTest() throws IOException {
Files.writeString(tempDir.resolve("a.txt"), "A");
}
@Test
void secondTest() throws IOException {
// tempDir 仍有效,但注意:两个测试共用同一目录,需自行管理文件隔离
assertTrue(Files.exists(tempDir.resolve("a.txt")));
}
配合文件操作常见注意事项
临时目录本身是干净的,但实际读写时还需注意:
- 不要硬编码路径拼接,始终用
tempDir.resolve("xxx")构建子路径 - 避免在测试中调用
System.getProperty("java.io.tmpdir")或File.createTempFile()——这会绕过@TempDir隔离机制 - 若被测代码内部强制依赖系统临时目录(如某些老库),需结合
System.setProperty+try-finally恢复,但应优先改造被测代码接受自定义路径参数 - 权限问题极少出现,但若测试涉及文件锁或跨进程访问,建议用
Files.createTempDirectory手动创建并显式清理(仅当@TempDir不适用时)
为什么不用自己 new File("tmp") 或手动 deleteOnExit
手动管理临时路径风险高:
-
deleteOnExit()在 JVM 异常退出时不保证执行,CI 环境易堆积垃圾 - 硬编码路径(如
"./tmp")导致测试不可重入、不支持并发执行 - 不同操作系统路径分隔符、权限策略差异易引发平台兼容问题
-
@TempDir由 JUnit 统一管控,天然支持多线程测试隔离和异常安全清理











