伴隨JUnit中 TemporaryFolder @Rule 的出現(xiàn),測試文件和目錄變得簡單了。
在 JUnit 中,規(guī)則(@Rule)可作為構(gòu)造測試用具(fixture)時初始化方法和清理方法的替代和補充(在 JUnit 中,這2種方法分別通過以下注解標注:org.junit.Before、org.junit.After、org.junit.BeforeClass 和 org.junit.AfterClass) 。而且規(guī)則的功能更加強大并且也更易于在項目和類之間共享。
譯者注:測試用具是指作為測試運行基準的一組對象所呈現(xiàn)的一個穩(wěn)定狀態(tài)。其目的是確保測試是運行在一個眾所周知的、穩(wěn)定的環(huán)境中的,以實現(xiàn)測試的可重復執(zhí)行。準備輸入數(shù)據(jù)、生成模擬對象(Mock)、將特定的數(shù)據(jù)加載到數(shù)據(jù)庫、復制一組特定的文件等,這些都屬于構(gòu)造測試用具。
待測試的代碼
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 中的靜態(tài)方法。
TemporaryFolder 提供了2個方法 newFile 和 newFolder,分別用于管理文件和目錄。這2個方法都可以返回所需要的對象。返回的文件或目錄都是由 setup 方法創(chuàng)建的并被存放在臨時目錄中。要想獲取臨時目錄自身的路徑,可以使用 TemporaryFolder 的 getRoot 方法。
無論測試成功與否,任何在測試過程中添加到臨時目錄的文件或目錄都會在測試結(jié)束時刪除。
本示例可以從我在 GitHub 上的項目 unit-testing-demo 中找到,除此之外該項目中還有很多其他示例可供諸位參考。