Laravel 框架类在 PHPUnit 数据提供程序中不可用

2022-08-30 22:47:13

我在Laravel中设置了类似的东西:

/app/controllers/MyController 中.php

class MyController extends BaseController {

    const MAX_FILE_SIZE = 10000;

    // ....

}

/app/tests/MyControllerTest 中.php

class MyControllerTest extends TestCase {

    public function myDataProvider() {
        return [
            [ MyController::MAX_FILE_SIZE ]
        ];
    }

    /**
     * @dataProvider myDataProvider
     */
    public function testMyController($a) {
        // Just an example
        $this->assertTrue(1 == 1);
    }
}

但是,当我运行时,我收到以下错误:vendor/bin/phpunit

PHP Fatal error:  Class 'Controller' not found in /home/me/my-app/app/controllers/BaseController.php on line 3

Fatal error: Class 'Controller' not found in /home/me/my-app/app/controllers/BaseController.php on line 3

如果我删除对中的类的引用并将其替换为文本常量,则测试成功完成。MyControllermyDataProvider()

此外,我可以将引用放在实际方法内部,并且测试也成功完成。MyController::MAX_FILE_SIZEtestMyController()

Laravel 框架类的自动加载设置似乎直到调用数据提供程序方法之后,但在调用实际测试方法之前才设置。有没有办法解决这个问题,以便我可以从PHPUnit数据提供程序中访问Laravel框架类?


注意:我直接从命令行调用PHPUnit,而不是从IDE内部调用PHPUnit(例如NetBeans)。我知道有些人对此有问题,但我认为这不适用于我的问题。


答案 1

正如本答案中所暗示的那样,这似乎与 PHPUnit 在任何测试用例中调用任何数据提供程序和方法的顺序有关。setUp()

PHPUnit 将在运行任何测试之前调用数据提供程序方法。在每个测试之前,它还将调用测试用例中的方法。Laravel 挂接到要调用的方法中,该方法会将控制器类添加到“包含路径”中,以便可以正确自动加载它们。setUp()setUp()$this->createApplication()

由于数据提供程序方法在发生这种情况之前运行,因此对数据提供程序内控制器类的任何引用都将失败。可以通过将测试类修改为如下所示来解决此问题:

class MyControllerTest extends TestCase {

    public function __construct($name = null, array $data = array(), $dataName = '') {
        parent::__construct($name, $data, $dataName);

        $this->createApplication();
    }

    public function myDataProvider() {
        return [
            [ MyController::MAX_FILE_SIZE ]
        ];
    }

    /**
     * @dataProvider myDataProvider
     */
    public function testMyController($a) {
        // Just an example
        $this->assertTrue(1 == 1);
    }
}

这将在运行数据提供程序方法之前调用,因此存在一个有效的应用程序实例,该实例将允许正确自动加载相应的类。createApplication()

这似乎有效,但我不确定它是否是最好的解决方案,或者它是否可能导致任何问题(尽管我想不出任何理由为什么它应该)。


答案 2

如果直接在 dataProvider 方法中创建应用程序,则测试初始化速度会快得多,尤其是在要测试大量项目的情况下。

public function myDataProvider() {
    $this->createApplication();

    return [
        [ MyController::MAX_FILE_SIZE ]
    ];
}

推荐