Нам нужно создать экземпляр Laravel вместе с базой данных, доступной для PHPUnit для запуска тестов с использованием реальных наборов данных. Не хрупкие насмешки. Во-первых, вы должны начинать ваши пакеты в изоляции по целому ряду причин, одна из которых верстак теперь осуждается в Laravel 5.
Итак, во-первых, мы должны dev-require
рамки Laravel в наш проект:
"require-dev": {
"phpunit/phpunit": "~4.0",
"phpspec/phpspec": "~2.1",
"laracasts/testdummy": "~2.0",
"laravel/laravel": "dev-develop"
},
сейчас мы можем создать абстрактный класс под названием DbTestCase
, из которого будут проходить все наши тесты. В этом классе мы будем разворачивать экземпляр Laravel и в памяти База данных SQLite для скорости.
Если мы продлим родной класс Laravel test Illuminate\Foundation\Testing\TestCase
, то некоторая работа уже была нами сделана. Нам просто нужно создать метод, который возвращает экземпляр Illuminate\Foundation\Application
.
/**
* Boots the application.
*
* @return \Illuminate\Foundation\Application
*/
public function createApplication()
{
$app = require __DIR__.'/../vendor/laravel/laravel/bootstrap/app.php';
$app->register('Path\To\Your\PackageServiceProvider');
$app->make('Illuminate\Contracts\Console\Kernel')->bootstrap();
return $app;
}
Обратите внимание на строку $app->register('Path\To\Your\PackageServiceProvider');
Это важно. Включите здесь путь поставщика пакетов услуг, поэтому мы зарегистрируем его с помощью нашего экземпляра Laravel, который находится в папке /vendor
.
Теперь у нас есть приложение Laravel, нам нужно настроить базу данных SQLite в памяти. Простой, Laravel-х TestCase
имеет setUp()
функцию, выполняемую перед тем когда-либо тест, позволяет сделать это там:
/**
* Setup DB before each test.
*
* @return void
*/
public function setUp()
{
parent::setUp();
$this->app['config']->set('database.default','sqlite');
$this->app['config']->set('database.connections.sqlite.database', ':memory:');
$this->migrate();
}
Я не буду давать много объяснений, как его вполне читаемым. Как вы можете видеть на последней строке, мы также вызываем $this->migrate()
, который, очевидно, выполняет наши миграции каждый раз, когда мы запускаем тест, давая нам новую БД для тестирования. Давайте посмотрим, как это работает:
/**
* run package database migrations
*
* @return void
*/
public function migrate()
{
$fileSystem = new Filesystem;
$classFinder = new ClassFinder;
foreach($fileSystem->files(__DIR__ . "/../src/Migrations") as $file)
{
$fileSystem->requireOnce($file);
$migrationClass = $classFinder->findClass($file);
(new $migrationClass)->up();
}
}
не вдаваться в подробности, в основном то, что мы делаем здесь, смотрит в src/Migrations
папку упаковки, требующей все файлы и затем запустить их миграции. Его грубая ситуация и требует больше проверок безопасности (я буду делать это в будущем), но она работает.
Почему бы не Artisan :: call ('migrate') ??
Простой! В Laravel 5 команда php artisan migrate --package='vendor/package'
устарела. Теперь ожидается, что разработчики создадут свои собственные команды для создания и перемещения файлов миграции в нужное место в приложении. Это гораздо более гибкий подход.
Я не могу использовать ClassFinder в Laravel 5.4. Есть ли альтернатива этому в 5.4? Я получаю ошибку Class 'Illuminate \ Filesystem \ ClassFinder' не найден –