У меня есть что-то вроде следующего в 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 Неустранимая ошибка: Class 'Controller' не найден в /home/me/my-app/app/controllers/BaseController.php в строке 3 Неустранимая ошибка: Class 'Controller' не найден в /home/me/my-app/app/controllers/BaseController.php в строке 3
Если я удалю ссылку на класс MyController
в myDataProvider()
и заменим его на константу литерала, то тест завершится успешно.
Кроме того, я могу разместить ссылки на MyController::MAX_FILE_SIZE
внутри фактического testMyController()
, и тест также завершится успешно.
Похоже, что установка автозагрузки для классов классов Laravel не устанавливается до тех пор, пока не будет вызван метод поставщика данных, но до того, как будут вызваны фактические методы тестирования. Есть ли способ обойти это, чтобы я мог получить доступ к классам классов Laravel из поставщика данных PHPUnit?
ПРИМЕЧАНИЕ. Я вызываю PHPUnit непосредственно из командной строки, а не из среды IDE (например, NetBeans). Я знаю, что у некоторых людей были проблемы с этим, но я не думаю, что это относится к моей проблеме.
Как подразумевается в этом ответе , это, по-видимому, связано с тем, что 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()
до того, как будут запущены методы поставщика данных, и поэтому существует допустимый экземпляр приложения, который позволит правильно createApplication()
соответствующие классы.
Кажется, это работает, но я не уверен, что это лучшее решение, или если это может вызвать какие-либо проблемы (хотя я не могу придумать никаких причин, почему это необходимо).
Тест будет инициализироваться намного быстрее, если вы создадите приложение прямо в методе dataProvider, особенно если у вас есть большой набор элементов для тестирования.
public function myDataProvider() { $this->createApplication(); return [ [ MyController::MAX_FILE_SIZE ] ]; }