Are there any Fake File System frameworks for Java?

JavaUnit TestingTestingMocking

Java Problem Overview


I am introducing tests in a project that makes heavy use of IO operations (the file system, in this case). The system constantly opens/closes files, checks if files exist, deletes them, etcetera.

It soon became obvious that regular mocking wouldn't be of much use, as that would make my tests hard to set up and reason about. On the other hand, having a fake file system would be awesome, and I think, pretty easy to set up.

It seems the ruby guys did it again, and there's exactly what I am asking for in ruby: http://ozmm.org/posts/fakefs.html.

Is there anything remotely similar for Java?

Java Solutions


Solution 1 - Java

Google has an open-source, in-memory implementation of Java 7's FileSystemProvider. The project is called jimfs.


If you use Java 6 or earlier, there is an alternative: I've used Apache Commons VFS before to great success. It seems to be much like the custom FileSystemProvider another answerer mentioned is in Java 7.

It comes pre-loaded with several file-system implementations: File, RAM, S/FTP, and Jar to name a few. I've also seen a plugin for S3.

Solution 2 - Java

In Java 6 and earlier it is difficult because classes like File and FileInputStream provide no way to dispatch to different "virtual file systems" in Java space.

In Java 7, there is support for virtual file systems; see Developing a Custom File System Provider. I don't know whether this will allow you to do what you want to do, but it is a good place to start looking.


> Meh. Being the fact that there doesn't seem to actually be any fake file system, I guess I'll just implement a minimal implementation by myself. I win nothing by using FileSystemProvider

Actually, you DO win by using FileSystemProvider:

  • You implement something that (if released under an open source license) could be very useful to other people in your position, and for other purposes.

  • You make it easier for yourself if you decide to switch to a FileSystemProvider that someone else might be working on right now.

Solution 3 - Java

You can use org.junit.rules.TemporaryFolder from the JUnit package:

> The TemporaryFolder Rule allows creation of files and folders that are guaranteed to be deleted when the test method finishes (whether it passes or fails):

Example:

final TemporaryFolder testFolder = new TemporaryFolder();
testFolder.create();
final Path filePath = testFolder.newFile("input.txt").toPath();
final Path dirPath = testFolder.newFolder("subfolder").toPath();

Alternatively quit the .toPath() part:

final File filePath = testFolder.newFile("input.txt");

Solution 4 - Java

You can abstract the use of File by using the intention of "somewhere to write data" by changing your API to use an OutputStream instead of a File, then pass the API a FileOutputStream in your production code, but pass it a ByteArrayOutputStream from your tests. A ByteArrayOutputStream is an in-memory stream, so it's very fast and you can simply inspect its contents by using its methods - it's perfect for testing. There's also the corresponding ByteArrayInputStream if you want to read data.

File systems are generally pretty fast - unless you were doing a great deal of File I/O in your tests, I wouldn't bother.

Note that creating a java File object does not create a file on disk, ie the following code doesn't cause any change to disk:

File f = new File("somepath"); // doesn't create a file on disk

Solution 5 - Java

Jimfs, by Google, is an in memory NIO filesystem, that's great for tests.

Solution 6 - Java

A simple way would be to use your system's way of providing a file system based totally on RAM - tempfs on Linux, a RAM disk on Windows.

Solution 7 - Java

MockFTPServer appears to have a couple of Fake Filesystem implementations (Unix/Windows)

It looks like you can use these fake filesystem implementations quite seperately from any FTP concepts. I'm trying this now for exactly the same pursposes as you've outlined.

Solution 8 - Java

i'm not sure about specific frameworks, but a general approach in terms of OOP would be to write some abstracted layers on top of any file access code (interfaces galore!) and perhaps a facade to ease use of common operations. then you just mock one layer below the code you are currently testing and it then essentially a fake file system (or at least the code you're testing won't know otherwise).

if you look into using a dependency injection framework to handle this for you it will ease the ability to switch out components for a faked implementation of an interface. if you follow the patterns of inversion of control, passing in any dependencies into the constructor of the class you are testing this will also make for easy 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
   }
}

i hope my java is correct, i haven't written java in a long while, but you will hopefully get the drift. hopefully i'm not underestimating the issue here and being overly simplistic!

of course this is all assuming you mean true unit testing, that is, testing the smallest possible units of code, and not an entire system. for integration testing a different approach is needed.

Solution 9 - Java

ShrinkWrap from the Arquillian project looks to include a NIO compliant in memory FileSystem

You can create a simple in memory FileSystem by doing the following:

FileSystem fs = ShrinkWrapFileSystems.newFileSystem(ShrinkWrap.create(GenericArchive.class))

Solution 10 - Java

Two other in memory file systems for java are,

memoryfilesystem

ephemeralfs

Both implement the NIO.2 File system api.

Solution 11 - Java

I was googling "Fake java FileSystem" and found this question. Unfortunately this is all I found. So I wrote this fake FileSystem myself: https://github.com/dernasherbrezon/mockfs

I'm using it for simulating IOExceptions during read/write to files. IOException could happen for example due to "no disk space", which is nearly impossible to simulate by other means.

Solution 12 - Java

Its a bit old and this solution seems to be linux only but it looks good https://www.google.co.il/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=tmpfs%20on%20ubuntu

tmpfs is an in-memory mapped directory (data disappears on reboot). Once mounted, Data can be copied into it and be worked on from memory.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questiondevoured elysiumView Question on Stackoverflow
Solution 1 - JavaMichael DeardeuffView Answer on Stackoverflow
Solution 2 - JavaStephen CView Answer on Stackoverflow
Solution 3 - Javathomas.mc.workView Answer on Stackoverflow
Solution 4 - JavaBohemianView Answer on Stackoverflow
Solution 5 - JavapronView Answer on Stackoverflow
Solution 6 - JavaPaŭlo EbermannView Answer on Stackoverflow
Solution 7 - JavaDeanoView Answer on Stackoverflow
Solution 8 - JavaWickyNilliamsView Answer on Stackoverflow
Solution 9 - JavaRob OxspringView Answer on Stackoverflow
Solution 10 - Javamostly alienView Answer on Stackoverflow
Solution 11 - JavaAndrey RodionovView Answer on Stackoverflow
Solution 12 - JavaozmaView Answer on Stackoverflow