Классы фреймворка 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: класс 'Controller' не найден в /home/me/my-app/app/controllers/BaseController.php в строке 3

Неустранимая ошибка: класс 'Controller' не найден в /home/me/my-app/app/controllers/BaseController.php в строке 3

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

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

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


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

10

Решение

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

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

15

Другие решения

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

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

return [
[ MyController::MAX_FILE_SIZE ]
];
}
10