伴随JUnit中 TemporaryFolder @Rule 的出现,测试文件和目录变得简单了。
在 JUnit 中,规则(@Rule)可作为构造测试用具(fixture)时初始化方法和清理方法的替代和补充(在 JUnit 中,这2种方法分别通过以下注解标注:org.junit.Before、org.junit.After、org.junit.BeforeClass 和 org.junit.AfterClass) 。而且规则的功能更加强大并且也更易于在项目和类之间共享。
译者注:测试用具是指作为测试运行基准的一组对象所呈现的一个稳定状态。其目的是确保测试是运行在一个众所周知的、稳定的环境中的,以实现测试的可重复执行。准备输入数据、生成模拟对象(Mock)、将特定的数据加载到数据库、复制一组特定的文件等,这些都属于构造测试用具。
待测试的代码
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("UTF8")), target);
}
测试类
public class FileWriterTest {
private FileWriter fileWriter = new FileWriter();
@Rule
public TemporaryFolder temporaryFolder = new TemporaryFolder();
@Rule
public ExpectedException thrown = ExpectedException.none();
@Test
public void throwsErrorWhenTargetFileExists() throws IOException {
// arrange
File output = temporaryFolder.newFile("output.txt");
thrown.expect(IOException.class);
thrown.expectMessage("file already exists");
// act
fileWriter.writeTo(output.getPath(), "test");
}
@Test
public void writesContentToFile() throws IOException {
// arrange
File output = temporaryFolder.newFolder("reports")
.toPath()
.resolve("output.txt")
.toFile();
// act
fileWriter.writeTo(output.getPath(), "test");
// assert
assertThat(output)
.hasContent("test")
.hasExtension("txt")
.hasParent(resolvePath("reports"));
}
private String resolvePath(String folder) {
return temporaryFolder
.getRoot().toPath()
.resolve(folder)
.toString();
}
}
译者注:第35行的 assertThat() 是类 org.assertj.core.api.Assertions 中的静态方法。
TemporaryFolder 提供了2个方法 newFile 和 newFolder,分别用于管理文件和目录。这2个方法都可以返回所需要的对象。返回的文件或目录都是由 setup 方法创建的并被存放在临时目录中。要想获取临时目录自身的路径,可以使用 TemporaryFolder 的 getRoot 方法。
无论测试成功与否,任何在测试过程中添加到临时目录的文件或目录都会在测试结束时删除。
本示例可以从我在 GitHub 上的项目 unit-testing-demo 中找到,除此之外该项目中还有很多其他示例可供诸位参考。