Mocking the Filesystem during BDD with Behat and PHPSpec

I was recently reading the excellent tutorial by Peter Suhm which describes a possible behaviour driven development workflow with Behat and PHPSpec. While I think he illustrates the workflow in a coherent way and manages to shed some light on why emergent design via BDD is a useful thing, one particular part of the tutorial didn’t seem right.

The main thing that could’ve been improved was the way the system was tested. Peter opted to physically read and write a file to disk when running the tests. I’m sure this was an attempt to simplify the example: it already covered a number of new and potentially confusing concepts, so introducing another one by mocking-out the file system may have been too much of the audience to swallow.

Already having had some experience with vfsStreamWrapper, the defacto standard library for mocking filesystems during tests, I decided to refactor the example code to use it.

Mocking the filesystem during testing

In order to make this work, we need to modify the composer.json file to include the library:

{
    "require-dev": {
        "behat/behat": "~3.0",
        "phpspec/phpspec": "~2.0",
        "mikey179/vfsStream": "[email protected]"
    },
    "autoload": {
        "psr-4": {
            "": "src/"
        }
    }
}

You’ll need a $ composer update after this.

Next, the key change is in the FeatureContext.php file. Instead of reading and writing the the file-system, we set up a variable that represents the state of the configuration file in array format (which we can modify), and then write it to the virtual file system stream wrapper. You can see this in the following except from FeatureContext.php:

Note that we use vfsStream::url(‘home/config.php’) to fetch the file path to be included. This ensures we talk to the vfs stream wrapper and not the actual filesystem.

It’s that simple.

You can also see the complete listing of the source files here: