Short version: For unit testing, I need an unreadable file to make sure the correct exception is thrown. Obviously, that unreadable file can't be stored by Git, so I chmod 000
at testing time and use git update-index --assume-unchanged
so that Git doesn't try storing the unreadable file. But then I can't checkout a different branch, but get the error "Your local changes to the following files would be overwritten by checkout."
Is there a better way to test, OR a better way to use Git so that everything plays nicely?
Long version: In one class, I have a method to read a file so that its contents can be imported into a database:
public function readFile($path) {
...
if(!is_readable($path))
throw new FileNotReadableException("The file $path is not readable");
...
}
I test that method using PHPUnit, and one test in particular should (indirectly) trigger the FileNotReadableException:
/**
* @expectedException Data\Exceptions\FileNotReadableException
*/
public function testFileNotReadableException() {
$file = '/_files/6504/58/6332_unreadable.xlsx';
@chmod(__DIR__ . $file, 0000);
$import = Import::find(58);
$import->importFile(array('ID'=>2, 'newFilename'=> $file), __DIR__);
}
After a test, git checkout other_branch
will abort:
error: Your local changes to the following files would be overwritten by checkout:
Data/Tests/_files/6504/58/6332_unreadable.xlsx
Please, commit your changes or stash them before you can switch branches.
Aborting
PHPUnit is a programmer-oriented testing framework for PHP. It is an instance of the xUnit architecture for unit testing frameworks. PHPUnit 9 is the current stable version. PHPUnit 10 is currently in development.
One of the most time-consuming parts of writing tests is writing the code to set the world up in a known state and then return it to its original state when the test is complete. This known state is called the fixture of the test.
How to Run Tests in PHPUnit. You can run all the tests in a directory using the PHPUnit binary installed in your vendor folder. You can also run a single test by providing the path to the test file. You use the --verbose flag to get more information on the test status.
You have a couple of options.
Add a tearDown()
method to the test that resets the file permissions so that git does not think that the file was modified. Then even if the test fails the file will be reset.
http://phpunit.de/manual/current/en/fixtures.html
public function tearDown() {
@chmod(__DIR__ . $file, 0755); //Whatever the old permissions were;
}
If you are using PHP 5.3+, you can use name-spacing and mock the is_readable
function. In your test file, override is_readable
with your own function. You will need to make sure that your override is in the same namespace as your class that you are testing.
http://www.schmengler-se.de/-php-mocking-built-in-functions-like-time-in-unit-tests
In your class you would do this:
namespace SUT
class SUT {
public function readFile($path) {
...
if(!is_readable($path))
throw new FileNotReadableException("The file $path is not readable");
...
}
}
Then in your test you do the following:
namespace SUT
function is_readable($filename) {
if (str_pos('unreadable') !== FALSE)) {
return false;
}
return true;
}
class SUTTest extends PHPUNIT_Framework_TestCase {
/**
* @expectedException Data\Exceptions\FileNotReadableException
*/
public function testFileNotReadableException() {
$file = '/_files/6504/58/6332_unreadable.xlsx';
$sut = new SUT();
$sut->readFile($file);
}
}
You would then not even have to include the files in your repo or worry about the permissions on it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With