2015-01-29 7 views
5

У меня возникает проблема при написании модульных тестов с помощью PHPUnit с использованием @dataProvider в приложении Laravel. Ошибка я получаю это:PHPUnit: «Класс« Красноречивый »не найден» при использовании @dataProvider

PHP Fatal error: Class 'Eloquent' not found in /path/to/project/app/models/ExampleClass.php on line 7

Похоже, константы, используемые в dataProvider является причиной фатального.

composer.json:

"psr-4": { 
    "Acme\\Models\\": "app/models" 
} 

phpunit.xml:

<?xml version="1.0" encoding="UTF-8"?> 
<phpunit backupGlobals="false" 
     backupStaticAttributes="false" 
     bootstrap="bootstrap/autoload.php" 
     colors="true" 
     convertErrorsToExceptions="true" 
     convertNoticesToExceptions="true" 
     convertWarningsToExceptions="true" 
     processIsolation="false" 
     stopOnFailure="false" 
     syntaxCheck="false" 
> 
    <testsuites> 
     <testsuite name="Application Test Suite"> 
      <directory>./app/tests/</directory> 
     </testsuite> 
    </testsuites> 
</phpunit> 

Пример Модель:

<?php 
namespace Acme\Models; 

use Eloquent; 

class ExampleClass extends Eloquent 
{ 
    /** 
    * @var bool 
    */ 
    const TRUE = true; 
} 

Пример испытаний Класс:

<?php 

use Acme\Models\ExampleClass; 

class ExampleClassTest extends TestCase 
{ 
    /** 
    * Example test. 
    * 
    * @param int $value 
    * @return void 
    * @dataProvider testExampleTestDataProvider 
    */ 
    public function testExampleTest($value) 
    { 
     $this->assertTrue($value); 
    } 

    /** 
    * Data provider for testExampleTest. 
    * 
    * @return array 
    */ 
    public function testExampleTestDataProvider() 
    { 
     return array(
      array(ExampleClass::TRUE), 
     ); 
    } 
} 

Стек след:

PHP Stack trace: 
PHP 1. {main}() /usr/local/bin/phpunit:0 
PHP 2. PHPUnit_TextUI_Command::main() /usr/local/bin/phpunit:612 
PHP 3. PHPUnit_TextUI_Command->run() phar:///usr/local/bin/phpunit/phpunit/TextUI/Command.php:138 
PHP 4. PHPUnit_TextUI_Command->handleArguments() phar:///usr/local/bin/phpunit/phpunit/TextUI/Command.php:148 
PHP 5. PHPUnit_Util_Configuration->getTestSuiteConfiguration() phar:///usr/local/bin/phpunit/phpunit/TextUI/Command.php:696 
PHP 6. PHPUnit_Util_Configuration->getTestSuite() phar:///usr/local/bin/phpunit/phpunit/Util/Configuration.php:837 
PHP 7. PHPUnit_Framework_TestSuite->addTestFiles() phar:///usr/local/bin/phpunit/phpunit/Util/Configuration.php:924 
PHP 8. PHPUnit_Framework_TestSuite->addTestFile() /path/to/project/vendor/phpunit/phpunit/src/Framework/TestSuite.php:400 
PHP 9. PHPUnit_Framework_TestSuite->addTestSuite() /path/to/project/vendor/phpunit/phpunit/src/Framework/TestSuite.php:374 
PHP 10. PHPUnit_Framework_TestSuite->__construct() /path/to/project/vendor/phpunit/phpunit/src/Framework/TestSuite.php:289 
PHP 11. PHPUnit_Framework_TestSuite->addTestMethod() /path/to/project/vendor/phpunit/phpunit/src/Framework/TestSuite.php:188 
PHP 12. PHPUnit_Framework_TestSuite::createTest() /path/to/project/vendor/phpunit/phpunit/src/Framework/TestSuite.php:842 
PHP 13. PHPUnit_Util_Test::getProvidedData() /path/to/project/vendor/phpunit/phpunit/src/Framework/TestSuite.php:465 
PHP 14. ReflectionMethod->invoke() /path/to/project/vendor/phpunit/phpunit/src/Util/Test.php:392 
PHP 15. ExampleClassTest->testExampleTestDataProvider() /path/to/project/vendor/phpunit/phpunit/src/Util/Test.php:392 
PHP 16. spl_autoload_call() /path/to/project/vendor/phpunit/phpunit/src/Util/Test.php:27 
PHP 17. Composer\Autoload\ClassLoader->loadClass() /path/to/project/vendor/phpunit/phpunit/src/Util/Test.php:0 
PHP 18. Composer\Autoload\includeFile() /path/to/project/vendor/composer/ClassLoader.php:278 
PHP 19. include() /path/to/project/vendor/composer/ClassLoader.php:386 
+0

Попробуйте использовать 'Eloquent'' вместо этого. Некоторые PHP-сборки необходимо указывать на корневое пространство имен. – Dencker

+0

@ Dencker, нет, это не помогает. ** Редактировать **: И не удаляет 'use Eloquent'' и использует' class ExampleClass extends \ Eloquent'. – JudRoman

ответ

7

У меня именно этот вопрос. Это связано с тем, что псевдонимы Laravel (например, Config::, Log:: ...) не были загружены в то время, когда вызывается метод @dataProvider. Здесь есть два решения, о которых я могу думать.

Решение 1

Изменить ваш @dataProvider так, что он не использует класс модели. В моем случае, я создавал модели объектов в методе @dataProvider, как это:

public function people() { 
    $person1 = new Person(); 
    $person1->name = "me"; 

    $person2 = new Person(); 
    $person2->name = "you"; 

    return [$person1, $person2]; 
} 

Поскольку Person класс упоминается в методе @dataProvider, он будет пытаться загрузить класс. Тогда он будет терпеть неудачу, потому что псевдоним класса Eloquent еще не создан Laravel.

Чтобы обойти эту проблему, я мог бы просто вернуть данные, а также создавать реальные объекты модели в самом тесте:

public function people() { 
    return ["me", "you"]; 
} 

public function testPerson($name) { 
    $person = new Person(); 
    $person->name = $name; 

    // Assertions... 
} 

В вашем случае, это означало бы возвращение [['true']], вместо [[ExampleClass::TRUE]].

Решение 2

я не вижу веских причин использовать Eloquent класса псевдоним здесь. На самом деле, я не знаю, почему он вообще существует (за исключением того, что он «выглядит» лучше?). Я привел это в канал IRC и не получил ответа ... Так что если есть причина использовать псевдоним здесь, то я этого не знаю.

При этом, если ваш класс модели расширяет базовый класс \Illuminate\Database\Eloquent\Model вместо псевдонима Eloquent, тогда ваши тесты начнут работать как есть.

<?php 
namespace Acme\Models; 

use \Illuminate\Database\Eloquent\Model; 

class ExampleClass extends Model 
{ 
    /** 
    * @var bool 
    */ 
    const TRUE = true; 
} 
+0

Я в основном реализовал ваше «решение 1», чтобы обойти его, прежде чем размещать вопрос здесь, но мне нравится «Решение 2» лучше. – JudRoman

+1

Решение 2 лучше! Благодаря! – klay

-3

Сначала необходимо включить автозагрузчик.

Что-то вроде:

require __DIR__.'/../vendor/autoload.php'; 

PHPUnit не загружается автозагрузчика для вас.

+1

Разве это не то, что 'bootstrap =" bootstrap/autoload.php "' находится в 'phpunit.xml'? Этот файл «требует __DIR __.»/../vendor/autoload.php '; ' – JudRoman

+0

Вы правы, я пропустил это. –

Смежные вопросы