在JUnit中使用@Rule測試檔案和目錄

ImportNew發表於2015-05-07

伴隨JUnit中 TemporaryFolder @Rule 的出現,測試檔案和目錄變得簡單了。

在 JUnit 中,規則(@Rule)可作為構造測試用具(fixture)時初始化方法和清理方法的替代和補充(在 JUnit 中,這2種方法分別通過以下註解標註:org.junit.Beforeorg.junit.Afterorg.junit.BeforeClassorg.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個方法 newFilenewFolder,分別用於管理檔案和目錄。這2個方法都可以返回所需要的物件。返回的檔案或目錄都是由 setup 方法建立的並被存放在臨時目錄中。要想獲取臨時目錄自身的路徑,可以使用 TemporaryFoldergetRoot 方法。

無論測試成功與否,任何在測試過程中新增到臨時目錄的檔案或目錄都會在測試結束時刪除。

本示例可以從我在 GitHub 上的專案 unit-testing-demo 中找到,除此之外該專案中還有很多其他示例可供諸位參考。

相關文章