I have something like the following set up in Laravel:

100年:

class MyController extends BaseController {

    const MAX_FILE_SIZE = 10000;

    // ....

}

In /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

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

In addition, I can place references to MyController::MAX_FILE_SIZE inside the actual testMyController() method, and the test also completes successfully.

It appears that the autoloading setup for Laravel framework classes isn't being set up until after the data provider method is being called, but before the actual test methods are called. Is there any way around this so that I can access Laravel framework classes from within a PHPUnit data provider?


NOTE:我直接从命令行调用PHPUnit,而不是从IDE(比如NetBeans)中调用.我知道有些人对此有意见,但我认为这不适用于我的问题.

推荐答案

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

PHPUnit will call the data provider methods before running any tests. Before each test it will also call the setUp() method in the test case. Laravel hooks into the setUp() method to call $this->createApplication() which will add the controller classes to the 'include path' so that they can be autoloaded correctly.

Since the data provider methods are run before this happens then any references to controller classes inside a data provider fail. It's possible work around this by modifying the test class to something like this:

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);
    }
}

This will call createApplication() before the data provider methods are run, and so there is a valid application instance that will allow the appropriate classes to be autoloaded correctly.

This seems to work, but I'm not sure if it's the best solution, or if it is likely to cause any issues (although I can't think of any reasons why it should).

Laravel相关问答推荐

发送邮箱后,Laravel重定向偶尔会导致错误500

AJAX响应中未定义的全名

在Laravel Sail Docker环境中的PHPMyAdmin中出现`Out of Memory‘错误

到查询构建器的MySQL查询

spatie 包 laravel-tags 在迁移中没有 down() 函数是有原因的吗

如何自定义密码确认不匹配.错误信息?

Laravel查询多对多关系

Laravel 5.2 无法打开 laravel.log

错误try 访问 null 类型值的数组偏移量laravel 5.8.26 Php 7.4.2

laravel 控制器中的全局变量

如何监控 Laravel 队列是否正在运行?

Laravel:Blade foreach 循环 bootstrap 列

SQLSTATE [HY000]:一般错误:1005 无法创建表 - Laravel 4

导入文件时如何跳过第一行

如何在 Laravel 中实现自己的 Faker 提供程序

如何访问 Carbon 对象类型?

使用 Laravel 将两个模型合并到一个分页查询中,并带有Eager加载的关系

Laravel Eloquent - 加入表时防止覆盖值

Laravel 仓库

Laravel:array_merge():参数#2不是数组错误