Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHPUnit: How do I mock this file system?

Consider the following scenario (this is not production code):

 class MyClass {
    public function myMethod() {
        // create a directory
        $path = sys_get_temp_dir() . '/' . md5(rand());
        if(!mkdir($path)) {
            throw new Exception("mkdir() failed.");
        }

        // create a file in that folder
        $myFile = fopen("$path/myFile.txt", "w");
        if(!$myFile) {
            throw new Exception("Cannot open file handle.");
        }
    }
}

Right, so what's the problem? Code coverage reports that this line is not covered:

throw new Exception("Cannot open file handle.");

Which is correct, but since I'm creating the folder above logically it would seem impossible for the fopen() to fail (except maybe in extreme circumstances, like disk at 100 %).

I could ignore the code from code coverage but thats kind of cheating. Is there any way I can mock the file system so that it can recognise myFile.txt and mock the file system unable to create the file?

like image 323
Elliot Chance Avatar asked Aug 23 '12 00:08

Elliot Chance


People also ask

Which method is used to create a mock with PHPUnit?

PHPUnit provides methods that are used to automatically create objects that will replace the original object in our test. createMock($type) and getMockBuilder($type) methods are used to create mock object. The createMock method immediately returns a mock object of the specified type.

Is PHPUnit a framework?

PHPUnit is a programmer-oriented testing framework for PHP. It is an instance of the xUnit architecture for unit testing frameworks. The currently supported versions are PHPUnit 9 and PHPUnit 8.

What is PHPUnit used for?

PHPUnit is a unit testing framework for the PHP programming language. It is an instance of the xUnit design for unit testing systems that began with SUnit and became popular with JUnit. Even a small software development project usually takes hours of hard work.

Is PHPUnit open source?

#3) PHPUnitIt is an open source testing tool used for PHP code. It is the most widely used framework for unit testing.


3 Answers

vfsStream is a stream wrapper for a virtual filesystem that is useful in unit tests to mock the real filesystem. You can install it from composer.

More Info at:

https://github.com/mikey179/vfsStream

https://phpunit.de/manual/current/en/test-doubles.html

like image 164
raidenace Avatar answered Sep 28 '22 03:09

raidenace


You could also break the function into 2 methods, one to create the path, and the other to use it. Then, individual tests could be done to ensure the path is created. A second set of tests could check and capture the exception when you try to use a bad path.

like image 32
Steven Scott Avatar answered Sep 28 '22 03:09

Steven Scott


Yes!

You should inject the full path somehow, and don't call sys_get_temp_dir() right in that method.

Any non-existant path should trigger a problem. You don't need VFS for that.

BUT you will get a E_NOTICE (or warning perhaps?) before the exception is triggered. So you should probably first check is_writable, and throw the exception if it returns false.

like image 45
Evert Avatar answered Sep 28 '22 03:09

Evert