2 minutes
Testing Legacy Code: Filesystem Interaction
This is the third article in the series of Testing Legacy Code. Check out the first part Testing Legacy Code: Echo Output in which I provide information about the origin of these examples.
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.
https://github.com/bovigo/vfsStream
Function with filesystem interaction
Given is a method which increments the counter persisted in the local filesystem.
<?php
declare(strict_types=1);
namespace RefactoringLegacyCode;
use function file_get_contents;
use function file_put_contents;
class FilesystemInteraction
{
public function countHit(): void
{
$count = file_get_contents(__DIR__ . '/hit_counter.txt');
file_put_contents(__DIR__ . '/hit_counter.txt', ++$count);
}
}
Before writing a test for it, a change to inject the dependency is required.
<?php
declare(strict_types=1);
namespace RefactoringLegacyCode;
use function file_get_contents;
use function file_put_contents;
class FilesystemInteraction
{
public function countHit(string $file = __DIR__ . '/hit_counter.txt'): void
{
$count = file_get_contents($file);
file_put_contents($file, ++$count);
}
}
Test
With the changed method, vfsStream can now be utilized to inject a virtual file for testing.
<?php
declare(strict_types=1);
namespace RefactoringLegacyCodeTest;
use org\bovigo\vfs\vfsStream;
use PHPUnit\Framework\TestCase;
use RefactoringLegacyCode\FilesystemInteraction;
class FilesystemInteractionTest extends TestCase
{
/**
* @covers \RefactoringLegacyCode\FilesystemInteraction::countHit
*/
public function test_countHit(): void
{
$vfs = vfsStream::setup();
$hitCounterFile = vfsStream::newFile('test_hit_counter.txt')
->at($vfs)
->setContent('1337');
$filesystemInteraction = new FilesystemInteraction();
$filesystemInteraction->countHit($hitCounterFile->url());
self::assertSame(
'1338',
$hitCounterFile->getContent()
);
}
}
Read other posts