为 PHPUnit 创建一个基本测试类并针对常见功能对其进行扩展会导致“找不到类”错误

2022-08-30 12:57:30

我正在运行PHPUnit,使用引导程序文件自动加载类(由作曲家生成)。

我所有的测试都很好地加载了类,但是对于我的两个测试,我做了一个扩展的“基”测试类(类似于PHPUnit7之前),然后是两个扩展基类的测试类,类似于下面的示例代码的结构:\PHPUnit\Framework\TestCasePHPUnit_Framework_TestCase

    abstract class BaseTest extends \PHPUnit\Framework\TestCase
    {
        abstract function setUp();

        protected function getCommonTestVariables()
        {
            // ...
        }

        protected function runCommonTests()
        {
            // ...
        }
    }
    class BlahBlahTest extends BaseTest
    {
        public function setUp()
        {
             $variables=$this->getCommonTestVariables();
             //etc...
        }

        public function testThings()
        {
            $this->runCommonTests();
        }
    }

每当我运行这个,PHPUnit都会给出一个错误:

致命错误:在 BlahBlahTest 中找不到类“BaseTest.php第 13 行

我已经检查了文件名,位置,命名空间,一切似乎都井井有条。任何帮助将不胜感激,以深入了解这一点


答案 1

我遇到了同样的问题,如果你不太熟悉PHPUnit和Composer的内部工作原理,这确实看起来很令人困惑。

PHPunit 不使用 Composer 自动加载程序来查找任何测试类。它只是扫描您提供的任何目录,并一次对一个文件进行操作。

因此,除了当前正在操作的文件中的类之外,它不知道任何其他类。这就是引导文件发挥作用的地方。

如果要使用 Composer 自动加载程序加载其他测试类,则需要告诉它在哪里可以找到这些测试类(以及可选的命名空间)。

有两种方法可以做到这一点:

  1. 将自动加载开发部分添加到您的 或composer.json
  2. 将测试目录添加到 Composer 自动加载程序

autoload-dev

这些部分允许您定义用于开发目的的自动加载规则。autoload-dev

直接引用手册

运行测试套件所需的类不应包含在主自动加载规则中,以避免在生产中以及当其他人将您的包用作依赖项时污染自动加载程序。

因此,最好依靠单元测试的专用路径,并将其添加到自动加载开发部分中。

例:

{
    "autoload": {
        "psr-4": { "MyLibrary\\": "src/" }
    },
    "autoload-dev": {
        "psr-4": { "MyLibrary\\Tests\\": "tests/" }
    }
}

添加到作曲家自动加载器

另一种方法是获取 Composer 自动加载程序和测试命名空间(如果有)以及测试所在的目录。如何执行此操作,如手册中所述(在“基本用法”中自动加载部分的底部)是:add

$loader = require('/path/to/vendor/autoload.php');
$loader->add('Test\\', __DIR__ . '/Tests');

如果测试使用镜像测试目录的命名空间,但仍然遇到问题,则可以尝试通过将第一个参数 () 替换为 来省略前缀。'Test\\'''


如果你想进一步了解所有这些是如何工作的,你应该看看Composer ClassLoader类,特别是和方法。add()findFile()


答案 2

对我来说,解决方案要简单得多。

  1. 我将 大写字母 更改为 在文件末尾和类名Testtest

BaseSomethingtest.php

<?php

namespace Something\Tests\Sub1\Sub2;

class BaseSomethingtest
{
}
  1. 我只是在基础类的末尾放了一个词。至于它没有结束,没有叫它Testphpunit

BaseSomethingTestCase.php

<?php

namespace Something\Tests\Sub1\Sub2;

class BaseSomethingTestCase
{
}

推荐