为 PHPUnit 创建一个基本测试类并将其扩展为常见功能会导致类未找到错误

Posted

技术标签:

【中文标题】为 PHPUnit 创建一个基本测试类并将其扩展为常见功能会导致类未找到错误【英文标题】:Creating a base test-class for PHPUnit and extending it for common functionality results in class not found error 【发布时间】:2013-09-23 16:12:30 【问题描述】:

我正在使用引导文件运行 phpUnit 以自动加载类(由 composer 生成)。

我所有的测试加载类都很好,但是对于我的两个测试,我创建了一个扩展 \PHPUnit\Framework\TestCase 的“基础”测试类(类似于 PHPUnit7 之前的 PHPUnit_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 都会报错:

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

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

【问题讨论】:

类是在一个文件中,还是在两个文件中?如果是后者,那么您必须包含该类,或者配置自动加载。 它们在两个文件中。正如我在帖子中所说,我有一个配置了 Composer 自动加载器的引导文件 作曲家自动加载器不能像魔术一样工作。它是否配置为自动加载您的 BaseTest 类?如果是:如何? 【参考方案1】:

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

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

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

如果您想使用 Composer Autoloader 加载其他测试类,您需要告诉它在哪里可以找到这些测试类(以及,可选地,在哪个命名空间中)。

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

    autoload-dev 部分添加到您的composer.json 或 将测试目录添加到 Composer Autoloader

使用autoload-dev

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

直接引用the manual:

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

因此,为您的单位使用专用路径是个好主意 测试并将其添加到 autoload-dev 部分中。

例子:


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

添加到 Composer 自动加载器

另一种方法是获取 Composer Autoloader 和 add 您的测试命名空间(如果有的话)和测试所在的目录。如何做到这一点,as described in the manual(在“基本用法”中自动加载部分的底部)是:

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

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


如果您想进一步了解所有这些工作原理,您应该查看Composer ClassLoader class,尤其是add()findFile() 方法。

【讨论】:

【参考方案2】:

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

    我把文件末尾Test的大写字母和类名改成了test

BaseSomethingtest.php

<?php

namespace Something\Tests\Sub1\Sub2;

class BaseSomethingtest


    我只是在我的基类末尾放了一个词。就它而言 没有以Test 结束,phpunit 没有调用它

BaseSomethingTestCase.php

<?php

namespace Something\Tests\Sub1\Sub2;

class BaseSomethingTestCase


【讨论】:

【参考方案3】:

我不确定您是否还需要解决方案,但这对我有用:Non-testable base class extending PHPUnit_Framework_TestCase

【讨论】:

【参考方案4】:

在 PHP 7.0+ 中extends PHPUnit_Framework_TestCase更改为extends \PHPUnit\Framework\TestCase,试试这个。

【讨论】:

以上是关于为 PHPUnit 创建一个基本测试类并将其扩展为常见功能会导致类未找到错误的主要内容,如果未能解决你的问题,请参考以下文章

显示大型数据表

c#类扩展器

如何在 Android 中将选项菜单添加到 Fragment

PHPUnit - 开发后创建测试

UICollectionView 未使用自定义 UIViewController 更新

为啥我在测试创建相同类的 phpUnit 静态方法后得到“无法加载模拟 MyClassConsumer,类已存在”?