So I'm currently picking up Unit testing and on my travels I've discovered I also might need to mock the file system as well as database queries and the like.
I've read a recommendation from the PHPUnit documentation that vfsStream is a good library for mocking the file system.
I'm having issues with using it, though.
I don't really understand how to set it up despite following documentation provided in the wiki hosted on GitHub.
I've abstracted file system interaction into it's own class with some aptly named methods. That doesn't appear to be the issue at hand, as when I wasn't mocking the file system it worked as intended.
Here is how I setup the test:
public function setUp()
{
// Setup here
$this->filesystem = new Filesystem;
vfsStreamWrapper::register();
$this->root = vfsStream::setup('test-dir');
}
Here is an example test I written to test for the creation of a directory:
public function testCanCreateDirectory()
{
$dir = vfsStream::url($this->root->path() . '/sub-dir');
$filesystem = $this->filesystem;
$filesystem->makeDirectory($dir);
$this->assertTrue($filesystem->isDirectory($dir));
}
That appears to work, so far so good. However, this next test fails:
public function testCanPutFile()
{
$file = $this->root->url() . '/sub-dir/test.txt';
$contents = "test text";
$filesystem = $this->filesystem;
$filesystem->put($file, $contents);
$this->assertTrue($filesystem->isFile($file));
$this->assertEquals($contents, $filesystem->get($file));
}
As far as I can tell from the documentation this should work, but obviously my reading of it isn't correct and I've gone awry somewhere along the lines.
Any hints as to how I can resolve this issue, as I've been changing lines over and over and cannot figure it out for the life of me.
Thank you in advance!
I appear to have solved this. The manner of the fix is... somewhat unsatisfactory, maybe someone could help explain the reasoning behind this I'd be happy.
public function testCanPutFile()
{
$dir = vfsStream::url($this->root->path()) . '/sub-dir';
$file = $dir . '/test.txt';
$contents = "test text";
$filesystem = $this->filesystem;
$this->assertTrue($filesystem->makeDirectory($dir));
$this->assertTrue($filesystem->isDirectory($dir));
$filesystem->put($file, $contents);
$this->assertTrue($filesystem->isFile($file));
$this->assertEquals($contents, $filesystem->get($file));
}
Is how I fixed the issue. It appears I have to recreate the structure per test method. I don't really understand why I have to do it this way. Maybe I'm missing something here but I can't see what I'm doing wrong and there are a paltry number of decent examples on the internet, with most of them found on the authors GitHub wiki. I do believe I've probably misread the documentation though, so a correction on this issue would also be much appreciated.