简短版本:对于单元测试,我需要一个不可读的文件以确保抛出正确的异常。显然,Git无法存储该不可读的文件,所以我在测试时chmod 000
使用git update-index --assume-unchanged
,以便Git不会尝试存储不可读的文件。但后来我不能签出一个不同的分支,但得到错误“您对以下文件的本地更改将被结帐覆盖。”
有没有更好的测试方法,或者更好的方式来使用Git以便一切都能很好地运行?
长版本:在一个类中,我有一个方法来读取文件,以便将其内容导入到数据库中:
public function readFile($path) {
...
if(!is_readable($path))
throw new FileNotReadableException("The file $path is not readable");
...
}
我使用PHPUnit测试该方法,特别是一个测试应该(间接)触发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__);
}
经过测试,git checkout other_branch
将中止:
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
答案 0 :(得分:6)
你有几个选择。
在测试中添加tearDown()
方法,重置文件权限,以便git不会认为该文件已被修改。然后即使测试失败,文件也会被重置。
http://phpunit.de/manual/current/en/fixtures.html
public function tearDown() {
@chmod(__DIR__ . $file, 0755); //Whatever the old permissions were;
}
如果您使用的是PHP 5.3+,则可以使用名称间距并模拟is_readable
函数。在您的测试文件中,使用您自己的函数覆盖is_readable
。您需要确保覆盖与您正在测试的类位于同一名称空间中。
http://www.schmengler-se.de/-php-mocking-built-in-functions-like-time-in-unit-tests
在课堂上你会这样做:
namespace SUT
class SUT {
public function readFile($path) {
...
if(!is_readable($path))
throw new FileNotReadableException("The file $path is not readable");
...
}
}
然后在测试中执行以下操作:
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);
}
}
您甚至不必将文件包含在您的仓库中或担心其权限。