我正在编写一个像Java中的应用程序一样的“Total Commander”。这里有非常明显的文件系统依赖。
我想对它进行单元测试。我为测试目的创建了目录结构,我将它保存在SVN存储库中的已知位置。到目前为止效果很好。
现在,我有一个应该忽略隐藏文件的方法。我怎么能这样做?我能以某种方式标记隐藏在SVN中的文件吗?
其他解决方案是在运行测试之前将其中一个文件隐藏在构建脚本中,但我担心这会将文件标记为已修改并始终显示在提交对话框中。
有什么建议吗?
答案 0 :(得分:10)
我会将测试目录的所有初始化都放入测试本身。这样的情况很简单:
答案 1 :(得分:3)
基本上,在单元测试时访问文件系统是一个很大的禁忌。对于初学者来说,这些测试比系统内测试慢(呃),因此降低了以高频率运行测试的可能性(例如每次编译)。
如果使用适配器模式抽象出对文件系统的访问,那就更好了。我是.NET开发人员,所以我的例子将在C#中,但我希望你能够简单地翻译它:
public class MyManager
{
private readonly IFileAdapter _fileAdapter;
public MyManager(IFileAdapter fileAdapter)
{
_fileAdapter = fileAdapter;
}
}
public interface IFileAdapter
{
public FileStream Open(string fileName);
public string ReadLine(FileStream fileStream);
// More methods...
}
public class FileAdapter : IFileAdapter
{
public FileStream Open(string fileName)
{
return System.Io.File.Open(fileName);
}
public string ReadLine(FileStream fileStream)
{
return File.Open(fileStream);
}
}
现在,像往常一样,您可以像提供返回的结果一样模拟文件系统。请记住 - 您 不 测试Java的IO类,假设它们有效。您只是在测试您的课程(例如上面示例中的 MyManager )。
将实际使用文件系统的测试留给您的集成/验收测试。
希望这有帮助, 阿萨弗。
答案 2 :(得分:2)
我更愿意抽象文件系统,这样我的单元测试就不需要访问真正的文件系统了。当然,这个抽象层必须使用真实文件系统进行测试,但这可以减少对它的依赖。
至于在SVN中存储隐藏文件,我是第二个artemb。您应该创建在JUnit设置中测试所需的所有文件。据推测,您应该更喜欢按测试方法设置(@Before
和@ After
)。但是,如果您遇到测试缓慢问题,请查看@BeforeClass
和@AfterClass
。我认为它们也可以用于测试套件。
答案 3 :(得分:0)
artemb的答案是正确的,您可以使用@Before和@After为每个测试创建和删除您的结构。
下面是我用来创建一个包含一些文件的新目录的代码,它会在系统temp目录中创建目录,这很重要,因为根据你的测试运行的机器,你可能不会允许在其他地方创建文件或目录。 (我必须编写此代码以允许我的测试在我们的Linux集成机器上执行...)
final String tempdir = System.getProperty("java.io.tmpdir");
final String dirname = Long.toHexString(System.currentTimeMillis());
final File dir = new File(tempdir, dirname);
dir.deleteOnExit();
dir.mkdir();
final String path = dir.getAbsolutePath();
assertTrue(dir.exists());
// pre condition, the directory is empty
assertTrue(dir.list().length == 0);
// create temp files in the directory
final int nbFiles = 3;
for (int i = 0; i < nbFiles; i++) {
(File.createTempFile("test", ".txt", dir)).deleteOnExit();
}
顺便说一下,你必须知道你运行的平台能够创建hiden文件......