2015-09-05 253 views
0

在Java應用程序中,我有一個類的方法,它只使用名稱保存文件。Junit在單元測試中保存文件的路徑

public void doSomething(){ 
    final File file = new File("XXX"+(new Random().next())+".txt"); 
    file.createNewFile(); 
} 

然後,與JUnit 4中一個單元測試,我運行執行該方法的類,我看到在項目的根文件夾名稱爲XXX.txt創建的文件。

@Test 
public void doSomethingTest() throws Exception{ 
    //call doSomething(); 
    Path path = //to project folder 
    Files.delete(path); 
} 

我怎樣才能得到這條道路動態,這樣我可以用一個@After方法來刪除它?

+0

只是調用'新文件('XXX.txt')。delete()'不工作從測試? – Codebender

+0

我說我有一個類的方法,而不是在@Test –

+0

@mat_boy註釋的方法,它不清楚你問的是什麼。是否從測試類創建文件是無關緊要的。如果它命名爲XXX.txt,則可以從測試中執行新的文件(「XXX.txt」)。delete(),並將其刪除。我**猜測**問題是您不知道文件的名稱,因爲它是在被測方法中動態生成的。如果是這樣,請在問題中說清楚。發佈真實代碼而不是僞代碼。所以我們知道它是如何動態生成的。 –

回答

6

最簡單的方法做的是讓你的代碼可測試性,允許其注入基本目錄下創建文件。

而不是

public Foo() { 
} 

public void doSomething() { 
    final File file = new File("XXX" + (new Random().next()) + ".txt"); 
    file.createNewFile(); 
} 

使用

private File baseDirectory; 

public Foo() { 
    this(new File(".")); 
} 

public Foo(File baseDirectory) { 
    this.baseDirectory = baseDirectory; 
} 

public void doSomething() { 
    final File file = new File(baseDirectory, "XXX" + (new Random().next()) + ".txt"); 
    file.createNewFile(); 
} 

現在您的測試可以創建一個臨時空目錄,把它傳遞給構造函數,調用該方法,檢查文件和測試後刪除。

這可能是您想要的一個功能,因爲總是在當前目錄中寫入對我來說不是一個好主意。

0

您可以使用file.getAbsolutePath()獲取完整的文件路徑,將其公開爲方法,然後在junit測試中將其刪除。

+0

該文件是在我測試的方法中創建的!我不返回方法 –

+0

好吧,甚至更好:將文件變量設置爲類變量(而不是方法變量),然後使用file.delete()在@ After方法中將其刪除。不要忘記在@ After之後檢查null。即:if(file!= null)file.delete(); – chrisl08

+0

似乎不是一個乾淨的解決方案。我不需要把它作爲一個類變量。我將創建多個文件,名稱將存儲在數據庫中最有可能 –

0

您可以使用Apache的commons-io。它有一個FileUtils類,可以做你想做的事。

下面是一個例子,實施及其測試 `

import java.io.File; 
import java.io.IOException; 

public class FileSave { 

    public static void main(String[] args) throws IOException { 
     FileSave fileSave = new FileSave(); 

     fileSave.saveFile("test.txt"); 
    } 

    public void saveFile(String fileName) throws IOException { 
     final File file = new File(fileName); 
     file.createNewFile(); 
     System.out.println("Hello"); 
    } 
} 

`

測試文件

`

import java.io.File; 

import org.apache.commons.io.FileUtils; 
import org.junit.Assert; 
import org.junit.Test; 

public class FileSaveTest { 


    @Test 
    public void checkFileSaved() throws Exception{ 
     FileSave fileSave = new FileSave(); 
     fileSave.saveFile("test.txt"); 
     Assert.assertTrue(FileUtils.deleteQuietly(new File("test.txt"))); 
     System.out.println(); 
    } 
} 

`

方法FileUtils.delete靜止將在刪除時返回true,否則返回false。

+0

中所述。但文件名不可用方法。在你的例子中,它是 –

+0

傳遞文件名作爲參數是個好主意。這樣它就會緊密結合在一起。並且可以重複使用以創建任何類型的文件名 –

2

我建議,如已經建議的那樣,改變源代碼並從外部傳遞父文件夾,最好在類構造函數中傳遞。

如果由於某種原因你不能這樣做,那麼你可以嘗試覆蓋user.dir系統屬性,它控制着當前的工作目錄,也就是默認創建文件的位置。

請注意,user.dir是全球性的,所以改變它會影響所有的類。例如,你將無法同時運行你的測試。

同樣在JUnit中,您可以使用TemporaryFolder規則,該規則將在測試開始前創建一個臨時目錄,並在測試完成後將其刪除。

示例(從javadoc的複製粘貼):

public static class HasTempFolder { 
    @Rule 
    public TemporaryFolder folder = new TemporaryFolder(); 

    @Test 
    public void testUsingTempFolder() throws IOException { 
     File createdFile = folder.newFile("myfile.txt"); 
     File createdFolder = folder.newFolder("subfolder"); 
     // ... 
    } 
} 
+0

有趣,但該文件夾在我測試的方法中定義。我無法將臨時文件夾傳遞給該方法。 –

+0

我建議,如已經建議的那樣,更改源代碼並從外部傳遞父文件夾,最好在類構造函數中傳遞。 –

+0

@mat_boy我已經更新了我的答案,添加了一個user.dir選項。 –