首页 > 解决方案 > Drupal 8 PHPUnit 测试自定义模块

问题描述

我试图找出为什么我的 PHPUnit 测试失败并显示以下消息:

PHP Warning:  Class 'PHPUnit\Framework\MockObject\Matcher\InvokedRecorder' not found in /var/www/html/core/tests/bootstrap.php on line 197

Warning: Class 'PHPUnit\Framework\MockObject\Matcher\InvokedRecorder' not found in /var/www/html/core/tests/bootstrap.php on line 197
PHP Warning:  Class 'Drupal\TestTools\PhpUnitCompatibility\PhpUnit8\HtmlOutputPrinter' not found in /var/www/html/core/tests/Drupal/Tests/Listeners/HtmlOutputPrinter.php on line 15

Warning: Class 'Drupal\TestTools\PhpUnitCompatibility\PhpUnit8\HtmlOutputPrinter' not found in /var/www/html/core/tests/Drupal/Tests/Listeners/HtmlOutputPrinter.php on line 15
PHPUnit 8.5.2 by Sebastian Bergmann and contributors.

Could not use "\Drupal\Tests\Listeners\HtmlOutputPrinter" as printer: class does not exist

../vendor/bin/phpunit ../modules/custom/drupalup_fibo_test/从核心目录内部执行,尽管我遵循教程并使用了github 上提供的导师完成的代码,但上面的错误还是涌现出来。

我也使用自己的自定义模块收到相同的消息。

可以通过注释掉core/phpunit.xml中的相关行来消除抱怨HtmlOutputPrinter的输出的最后一行。

我的研究使我看到了这个问题日志和其他类似的问题,其中 PHPUnit 6 和 PHP 兼容性问题似乎是问题所在。我的 Drupal 站点由 Docker 驱动,使用 PHPUnit 8.5.2 并运行 PHP 7.3.13。

标签: drupalphpunitdrupal-8

解决方案


11/2020 更新:Drupal 9 与 PhpUnit 8 兼容。-
> 我建议升级到 Drupal 9。

下面的旧答案:

Drupal 8.8 还不支持 PhpUnit 8。

PHPUnit 7 将于 2020 年 2 月 7 日终止支持

https://www.drupal.org/project/drupal/issues/3063887

但是,如果您从 stacktrace 中查看该位置,core/tests/bootstrap.php您会发现:

// PHPUnit 4 to PHPUnit 6 bridge. Tests written for PHPUnit 4 need to work on
// PHPUnit 6 with a minimum of fuss.
// @todo provided for BC; remove in Drupal 9.
class_alias(AssertionFailedError::class, '\PHPUnit_Framework_AssertionFailedError');
class_alias(Count::class, '\PHPUnit_Framework_Constraint_Count');
class_alias(Error::class, '\PHPUnit_Framework_Error');
class_alias(Warning::class, '\PHPUnit_Framework_Error_Warning');
class_alias(ExpectationFailedException::class, '\PHPUnit_Framework_ExpectationFailedException');
class_alias(Exception::class, '\PHPUnit_Framework_Exception');
class_alias(InvokedRecorder::class, '\PHPUnit_Framework_MockObject_Matcher_InvokedRecorder');
class_alias(SkippedTestError::class, '\PHPUnit_Framework_SkippedTestError');
class_alias(TestCase::class, '\PHPUnit_Framework_TestCase');
class_alias(Test::class, '\PHPUnit_Util_Test');
class_alias(Xml::class, '\PHPUnit_Util_XML');

因此,您可以简单地InvokedRecorder手动删除该行或应用问题 #3063887 中的一个补丁(见上文)。

现在,我创建了一个最小的补丁来删除这个引用......

diff --git a/core/tests/bootstrap.php b/core/tests/bootstrap.php
index 467e6af6e6..ca3b579b6c 100644
--- a/core/tests/bootstrap.php
+++ b/core/tests/bootstrap.php
@@ -14,7 +14,6 @@
 use PHPUnit\Framework\Error\Warning;
 use PHPUnit\Framework\ExpectationFailedException;
 use PHPUnit\Framework\Exception;
-use PHPUnit\Framework\MockObject\Matcher\InvokedRecorder;
 use PHPUnit\Framework\SkippedTestError;
 use PHPUnit\Framework\TestCase;
 use PHPUnit\Util\Test;
@@ -194,7 +193,6 @@ class_alias(Error::class, '\PHPUnit_Framework_Error');
 class_alias(Warning::class, '\PHPUnit_Framework_Error_Warning');
 class_alias(ExpectationFailedException::class, '\PHPUnit_Framework_ExpectationFailedException');
 class_alias(Exception::class, '\PHPUnit_Framework_Exception');
-class_alias(InvokedRecorder::class, '\PHPUnit_Framework_MockObject_Matcher_InvokedRecorder');
 class_alias(SkippedTestError::class, '\PHPUnit_Framework_SkippedTestError');
 class_alias(TestCase::class, '\PHPUnit_Framework_TestCase');
 class_alias(Test::class, '\PHPUnit_Util_Test');

...可以添加到composer.json

{
  "patches": {
    "drupal/core": {
      "Remove InvokedRecorder for PhpUnit 8": "src/patches/3063887-InvokedRecorder.patch"
    }
  }
}

推荐阅读