PHPUnit:你能排除第三方库将其通知转换为异常的情况吗?带有convertNoticesToExceptions的E



我一直在运行PHPUnit,并将convertNoticesToExceptions作为最佳实践打开。https://phpunit.readthedocs.io/en/9.5/configuration.html#the-convertnoticestoexceptions属性

当然,这只适用于我自己的代码:我更喜欢为(例如(vendor/设置不同的设置。我并不是要修复所有由第三方代码引发的通知。

文档中没有建议不同目录的设置可能不同。(我隐约记得读过一篇关于忽视图书馆通知的文章,但可能是错误的。(

我知道使用@,但这解决了另一个问题。

这不是一种选择吗?

为了简洁起见,假设您的项目中有两个类:

namespace MyNamespace;
class Foo
{
public function myFunc(): bool
{
$i = [];
$i["1"];
return true;
}
}
namespace MyNamespace;
class Bar
{
public function myFunc(): bool
{
$i = [];
$i["1"];
return true;
}
}

两个函数myFunc都会触发w警告(在PHP8.1中不知道什么会触发通知(,但我们不想为类Foo报告它。

你的测试会是这样的:

namespace MyNamespaceTests;
use PHPUnitFrameworkTestCase;
use MyNamespaceFoo;
use MyNamespaceBar;
class MyTest extends TestCase
{
protected function setUp(): void
{
set_error_handler(static function (int $errorNr, string $errorStr, string $errorFile, int $errorLine, array $errorContext = []): bool {
if (str_contains('/home/awons/Projects/test/src/Foo.php', $errorFile) && $errorNr === E_WARNING) {
return true;
}

$phpUnitHandler = new PHPUnitUtilErrorHandler(true, true, true, true);
return $phpUnitHandler->__invoke($errorNr, $errorStr, $errorFile, $errorLine, $errorContext);

});
}
protected function tearDown(): void
{
restore_error_handler();
}
public function testFoo(): void
{
$foo = new Foo();
self::assertTrue($foo->myFunc());
}
public function testBar(): void
{
$bar = new Bar();
self::assertTrue($bar->myFunc());
}
public function testFooAgain(): void
{
$foo = new Foo();
self::assertTrue($foo->myFunc());
}
}

这并不是最具性能的解决方案,我认为这是一个黑客攻击,但如果你需要的话,它应该会奏效。

您所要做的就是决定何时触发PhpUnit的错误处理程序,以及何时忽略通知。您可以将/home/awons/Projects/test/src/Foo.php替换为/vendor/(或者任何更具体的东西,以100%确保获得正确的路径(。

此外,我不知道如何获得错误处理程序的当前设置。您可能需要为此解析配置文件,或者只需将所有内容移动到基类并在那里硬编码值(只需使它们与实际设置同步(。

::编辑::甚至有一种方法不实例化PhpUnit的处理程序,而只是从当前上下文中获取它。我们所要做的就是注册一个空的错误处理程序并立即恢复它。注册新的错误处理程序将返回上一个错误处理程序。假设基类在./tests中,您可以构建以下抽象测试用例:

use PHPUnitFrameworkTestCase;
abstract class BaseTestCase extends TestCase
{
protected function setUp(): void
{
$phpUnitErrorHandler = set_error_handler(function () {
});
restore_error_handler();
set_error_handler(
static function (
int $errorNr,
string $errorStr,
string $errorFile,
int $errorLine,
array $errorContext = []
) use ($phpUnitErrorHandler): bool {
$vendorDir = realpath(__DIR__ . "/../vendor/");
if (str_contains($vendorDir, $errorFile) && $errorNr === E_NOTICE) {
return true;
}
return call_user_func_array(
$phpUnitErrorHandler,
[$errorNr, $errorStr, $errorFile, $errorLine, $errorContext]
);
}
);
}
protected function tearDown(): void
{
restore_error_handler();
}
}

相关内容

最新更新