2015-09-05 83 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选项。 –