Some minutes ago I released the first version of vfsStream. vfsStream is a stream wrapper for a virtual file system that may be helpful in unit tests to mock the real file system. It can be used with any unit test framework, like PHPUnit or SimpleTest.
The first idea for this came up when I prepared my talk about stream wrappers for the PHP conference in Frankfurt-Mörfelden earlier this year (slides still available). Everybody knows that you should not use real databases in unit tests, so why should one use the real file system? Of course you can create an IO abstraction layer, but PHP offers such easy access to file contents via its file_get_content() and file_put_content() functions as well as with its other file system functions that it would be a bit overdone to create such a layer just for testing purposes. Additionally there are stream wrappers which allow you to create your own protocol and use it with exactly this file functions.
This was the point where I started thinking about it, so hacked together a first version as a prove-of-concept. Because it worked like a charm I started to use it in my own unit tests, which already saved me some time and problems. Today I decided it is time to release this as open source to the public to see if other people like the idea and have a use for it, therefore I did some refactorings, and did a first release. Unfortunately not everything works by now: It is currently not possible to rename a file or directory, and it is not possible to remove directories. Additionally file modes are completely ignored. The main reason for this is that I did not need one of this features until now. Feel free to send patches, wait until I have a need for it or beg me to implement them.
It does not reset the wrapper, as reconfiguring can be done by setting a new root object with vfsStreamWrapper::setRoot(), but it might be a good idea to reset it as well when being called. I will think about this.
>Everybody knows that you should not use
> real databases in unit tests, so why
> should one use the real file system?
I'd disagree strongly with that. Classes which interact with a database via some kind of a Connection object should be tested with a real database rather than a mock Connection (more here: http://aperiplus.sourceforge.net/testing-data-access-classes.php).
I would argue the same for tests which need to interact with a filesystem. As a rule, whenever I hit an application boundary I'd be thinking about testing with the real resource (you'll probably want to extend your testing framework with some custom test cases and expectations).
People's needs may differ but I never have a problem with large suites of database/filesystem tests. Subversion fixtures are about the only thing I've found which make a real hit on performance.
Contrasting with Noel, I very rarely test against a real database, and usually when it's a data access/abstraction layer where there's no lower/inner class to mock.
Not so sure about the filesystem since it's not subject to as much variance (except maybe on Windows where filesystem functions on XP tend not to be able to delete directories, for example - another boghole Vista fixed thankfully). I do think it's worth persuing however, and I'm keeping an eye on it .