有没有Java的假文件系统框架?
我在一个大量使用IO操作的项目中引入了testing(在本例中是文件系统)。 系统不断打开/closures文件,检查文件是否存在,删除它们等等。
很明显,经常嘲笑不会太有用,因为这会使我的testing很难设置和推理。 另一方面,有一个假的文件系统将是非常棒的,我觉得很容易设置。
看来ruby的人再次这样做了,这正是我所要求的ruby: http : //ozmm.org/posts/fakefs.html 。
有没有什么远程类似的Java?
我之前使用Apache Commons VFS取得了巨大的成功。 这似乎很像自定义的FileSystemProvider另一个答案是在Java7中提到。
它预装了几个文件系统实现:文件,RAM,S / FTP和Jar等。 我也看到了S3的一个插件 。
更新(3年后)
Google有一个Java 7的FileSystemProvider的开源内存实现。 该项目被称为jimfs 。
如果您更喜欢使用Apache API上的标准API,那么这是一个巨大的胜利。
在Java 6及更早的版本中,这很难实现,因为像File
和FileInputStream
这样的类没有办法派发到Java空间中不同的“虚拟文件系统”。
在Java 7中,支持虚拟文件系统; 请参阅开发自定义文件系统提供者 。 我不知道这是否会让你做你想做的事情,但这是一个开始寻找的好地方。
咩。 事实上,似乎没有任何假的文件系统,我想我只是自己实现一个最小的实现。 使用FileSystemProvider我什么也没赢
其实,你使用FileSystemProvider获胜:
-
你实现的东西(如果在开源许可证下发布的话)可能对你所在的其他人非常有用,也可能用于其他目的。
-
如果您决定切换到其他人可能正在处理的文件系统提供程序,则可以让自己更轻松。
通过改变你的API来使用OutputStream
而不是File
,然后在你的产品代码中传递一个FileOutputStream
的API,但是把你的testing中的ByteArrayOutputStream
传递给你,你可以通过使用“某处写数据” 。 ByteArrayOutputStream
是一个内存stream,因此速度非常快,您可以使用它的方法简单地检查它的内容 – 这对testing来说非常合适。 如果你想读取数据,还有相应的ByteArrayInputStream
。
文件系统通常是相当快的,除非你在testing中做了大量的文件I / O,我不会麻烦。
请注意,创buildjava File
对象不会在磁盘上创build文件,即以下代码不会导致对磁盘进行任何更改:
File f = new File("somepath"); // doesn't create a file on disk
Google的Jimfs是内存中的NIO文件系统,这对于testing非常有用 。
您可以使用JUnit包中的org.junit.rules.TemporaryFolder
:
TemporaryFolder规则允许创build文件和文件夹,当testing方法完成时(无论是否通过),这些文件和文件夹将被保证删除:
例:
final TemporaryFolder testFolder = new TemporaryFolder(); testFolder.create(); final Path filePath = testFolder.newFile("input.txt").toPath(); final Path dirPath = testFolder.newFolder("subfolder").toPath();
或者退出.toPath()
部分:
final File filePath = testFolder.newFile("input.txt");
一个简单的方法是使用你的系统提供一个完全基于RAM的文件系统的方式 – Linux上的tempfs ,Windows上的RAM磁盘 。
MockFTPServer似乎有几个伪文件系统实现(Unix / Windows)
看起来你可以从任何FTP概念中单独使用这些伪造的文件系统实现。 我现在正在尝试这个,就像你所描述的一样。
我不确定具体的框架,但是从OOP的angular度来看,一般的方法是在任何文件访问代码(接口嘉豪!)或者外观的基础上编写一些抽象层来简化常用操作的使用。 那么你只是嘲笑你正在testing的代码下面的一层,然后基本上是一个假的文件系统(或者至less你正在testing的代码将不知道)。
如果您考虑使用dependency injection框架来为您处理这个问题,那么它将减轻为了伪造接口的实现而切换组件的能力。 如果遵循控制反转的模式,将任何依赖关系传递给正在testing的类的构造函数,这也将使testing变得简单。
public interface IFileSystem { IFileHandle Load(string path); //etc } public class ClassBeingTested { public ClassBeingTested(IFileSystem fileSystem) { //assign to private field } public void DoSomethingWithFileSystem() { //utilise interface to file system here //which you could easily mock for testing purposes //by passing a fake implementation to the constructor } }
我希望我的Java是正确的,我很久没有写Java了,但你会希望得到漂移。 希望我不会低估这个问题,过于简单!
当然这都假设你的意思是真正的unit testing,也就是testing最小的代码单元,而不是整个系统。 对于集成testing,需要一个不同的方法。
来自Arquillian项目的ShrinkWrap看起来在内存FileSystem中包含了一个兼容NIO
您可以通过执行以下操作来创build简单的内存文件系统:
FileSystem fs = ShrinkWrapFileSystems.newFileSystem(ShrinkWrap.create(GenericArchive.class))
另外两个在java内存中的文件系统,
memoryfilesystem
ephemeralfs
两者都实现了NIO.2文件系统API。
它有点老,这个解决scheme似乎只是Linux,但它看起来不错https://www.google.co.il/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=tmpfs%20on% 20ubuntu
tmpfs是一个内存映射的目录(重启后数据会消失)。 一旦安装,数据可以复制到它并从内存工作。