Классы фреймворка Laravel недоступны в поставщике данных PHPUnit


У меня в 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

Если я удалю ссылку на класс MyController в myDataProvider() и заменю ее литеральной константой, то тест завершится успешно.

Кроме того, я могу разместить ссылки на MyController::MAX_FILE_SIZE внутри фактического метода testMyController(), и тест также завершится успешно.

Похоже, что настройка автоматической загрузки для классов фреймворка Laravel не настраивается до после вызова метода поставщика данных, но до вызываются фактические методы тестирования. Есть ли какой-либо способ обойти это, чтобы я мог получить доступ к классам фреймворка Laravel из поставщика данных PHPUnit?


ПРИМЕЧАНИЕ: Я вызываю PHPUnit непосредственно из командной строки, а не из среды IDE (например, NetBeans). Я знаю, что у некоторых людей были проблемы с этим, но я не думаю, что это относится к моей проблеме.

Author: FixMaker, 2014-11-03

2 answers

Как подразумевается в этом ответе , это, по-видимому, связано с порядком, в котором PHPUnit будет вызывать любых поставщиков данных и метод setUp() в любых тестовых случаях.

PHPUnit вызовет методы поставщика данных перед выполнением любых тестов. Перед каждым тестом он также будет вызывать метод setUp() в тестовом примере. Laravel подключается к методу 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() до запуска методов поставщика данных, и поэтому существует допустимый экземпляр приложения, который позволит правильно загружать соответствующие классы.

Кажется, это работает, но я не уверен, что это лучшее решение, или если это может вызвать какие-либо проблемы (хотя я не могу придумать никаких причин, по которым это должно произойти).

 14
Author: FixMaker, 2017-05-23 12:26:35

Тест инициализируется намного быстрее, если вы создадите приложение прямо в методе dataProvider, особенно если у вас есть большой набор элементов для тестирования.

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

    return [
        [ MyController::MAX_FILE_SIZE ]
    ];
}
 8
Author: Alexander Gorbatenko, 2015-10-23 11:30:16