作为最佳实践,我一直在运行 PHPUnit 并启用 convertNoticesToExceptions。 https://phpunit.readthedocs.io/en/9.5/configuration.html#the-convertnoticestoexceptions-attribute
当然,这只适用于我自己的代码:我更愿意为(例如)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 警告(不知道什么会在 PHP 8.1 中触发通知),但我们不想为类 Foo
报告它.
您的测试将如下所示:
namespace MyNamespace\Tests;
use PHPUnit\Framework\TestCase;
use MyNamespace\Foo;
use MyNamespace\Bar;
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 \PHPUnit\Util\ErrorHandler(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());
}
}
这并不是最高效的解决方案,我认为它是一种 hack,但如果您需要的话,它应该可以解决问题。
您所要做的就是决定何时触发 PhpUnit 的错误处理程序以及何时忽略通知。您可以将 /home/awons/Projects/test/src/Foo.php
替换为 /vendor/
(或任何更具体的内容以 100% 确定您获得了正确的路径).
此外,我不确定如何获取错误处理程序的当前设置。您可能需要为此解析配置文件,或者只是将所有内容移动到基类并在那里硬编码值(只是让它们与实际设置同步)。
::编辑::
甚至还有一种方法可以不实例化 PhpUnit 的处理程序,而只是从当前上下文中获取它。我们所要做的就是注册一个空的错误处理程序并立即恢复它。注册一个新的错误处理程序会返回前一个错误处理程序。
假设基类在 ./tests
中,您可以构建以下抽象测试用例:
use PHPUnit\Framework\TestCase;
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();
}
}
关于PHPUnit:您能否排除第 3 方库将其通知转换为异常?带有 convertNoticesToExceptions 的 EG,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73152935/