gpt4 book ai didi

fopen/fwrite 链的 PHPUnit 测试

转载 作者:行者123 更新时间:2023-12-04 17:19:11 26 4
gpt4 key购买 nike

在一个项目中我发现了这样的代码行:

protected function save($content, $path)
{
// ...
if (($handler = @fopen($path, 'w')) === false) {
throw new Exception('...');
}

// ...
if (@fwrite($handler, $content) === false) {
throw new Exception('...');
}

// ...
@fclose($handler);
}

我想用 PHPUnit 测试这个方法,但我有点卡在正确的测试用例上。如果我将传递不正确的 $path 或具有不正确权限的正确的 $path(例如 0444),那么一切都会在第一个异常处停止。如果我以正确的权限传递正确的 $path,那么 PHP 也将能够写入该文件,并且不会出现第二个异常。

那么有没有办法不重写这个方法就可以测试第二个异常呢?

或者最好在一种情况下同时检查 fopenfwrite 并且两者只使用一个异常?

或者最好的选择是将此方法分成两种 - 一种用于打开,一种用于写入 - 并分别进行测试?

最佳答案

实现目标的最佳方法是使用模拟文件系统。我建议使用 vfsStream :

$ composer require mikey179/vfsStream

首先我要提到的是,如果您使用无效参数调用此函数,fread 只会返回 false。如果发生任何其他错误,它将返回已写入的字节数。所以你必须添加另一张支票:

class SomeClass {
public function save($content, $path)
{
// ...
if (($handler = @fopen($path, 'w')) === false) {
throw new Exception('...');
}

$result = @fwrite($handler, $content);

// ...
if ($result === false) { // this will only happen when passing invalid arguments to fwrite
throw new Exception('...');
}

// ...
if ($result < strlen($content)) { // additional check if all bytes could have been written to disk
throw new Exception('...');
}

// ...
@fclose($handler);
}
}

该方法的测试用例可能如下所示:

class SomeClassTest extends \PHPUnit_Framework_TestCase {

/**
* @var vfsStreamDirectory
*/
private $fs_mock;

/**
* @var vfsStreamFile
*/
private $file_mock;

/**
* @var $sut System under test
*/
private $sut;

public function setUp() {
$this->fs_mock = vfsStream::setup();
$this->file_mock = new vfsStreamFile('filename.ext');
$this->fs_mock->addChild($this->file_mock);

$this->sut = new SomeClass();
}

public function testSaveThrowsExceptionOnMissingWritePermissionOnFile() {
$this->expectException(\Exception::class);

$this->file_mock->chmod(0);
$this->sut->save(
'content',
$this->file_mock->url()
);
}

public function testSaveThrowsExceptionOnMissingWritePermissionOnDirectory() {
$this->expectException(\Exception::class);

$this->fs_mock->chmod(0);
$this->sut->save(
'content',
$this->fs_mock->url().'/new_file.ext'
);
}

public function testSaveThrowsExceptionOnInvalidContentType() {
$this->expectException(\Exception::class);

$this->fs_mock->chmod(0);
$this->sut->save(
$this,
$this->file_mock->url()
);
}

public function testSaveThrowsExceptionOnDiskFull() {
$this->expectException(\Exception::class);

$this->fs_mock->chmod(0777); // to be sure
$this->file_mock->chmod(0777); // to be sure

vfsStream::setQuota(1); // set disk quota to 1 byte

$this->sut->save(
'content',
$this->file_mock->url()
);
}
}

我希望我能帮助...

关于fopen/fwrite 链的 PHPUnit 测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35290479/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com