Ali
Ali

Reputation: 3081

How to mock readonly directory using PHPUnit and VFSstream

I have a simple open (file) method which should throw an exception if it fails to open or create a file in the given path:

const ERR_MSG_OPEN_FILE = 'Failed to open or create file at %s';

public function open($filePath)
{
    ini_set('auto_detect_line_endings', TRUE);

    if (false !== ($this->handler = @fopen($filePath, 'c+'))) {
        return true;
    } else {
        throw new \Exception(
            sprintf(self::ERR_MSG_OPEN_FILE, $filePath)
        );
    }
}

There is unit-test around it using PHPUnit and VFSStream:

$structure = [
        'sample.csv' => file_get_contents(__DIR__ . '/../sampleFiles/small.csv')
    ];

$this->root = vfsStream::setup('exampleDir', null, $structure);

$existingFilePath = vfsStream::url('exampleDir') . DIRECTORY_SEPARATOR . 'sample.csv';

$this->file = new File();
$this->file->open($existingFilePath);

The above setup creates a virtual directory structor containing a mock file (read/cloned from an existing CSV file) and this satisfy the open method's requirement to open a file. And also if I pass a different path (none existing file) it will be created in the same virtual structor.

Now in order to cover the exception I want to add a ready-only directory to the existing structor, lets say a folder belong to another user and I don't have write permission on it, like this when I try to open a non existing file in that folder, attempt to creating one should fail and the open method should throw the exception.

The only problem is,.... I don't know how to do it :D

Any Advice, hint and guidance will be appreciated :)

Upvotes: 1

Views: 529

Answers (1)

user5060359
user5060359

Reputation:

You could simply point your mock directory's url to an incorrect path.

$existingFilePath = vfsStream::url('badExampleDir') . DIRECTORY_SEPARATOR . 'incorrect.csv';

considering the badExampleDir never been setup your method will fail to create the file in it.

Upvotes: 0

Related Questions