Я пытаюсь запустить мой модульный тест и создать базу данных во время установки. По какой-то причине я получаю ошибку Unknown database 'coretest'
. Если я создаю базу данных, хотя вручную и запускаю тест, тогда я получаю Can't create database 'coretest'; database exists
Can't create database 'coretest'; database exists
.
Оператор базы данных drop работает только сейчас в базе данных create.
Вот мои методы setUP и tearDown:
class TestCase extends Illuminate\Foundation\Testing\TestCase { /** * Default preparation for each test */ public function setUp() { parent::setUp(); DB::statement('create database coretest;'); Artisan::call('migrate'); $this->seed(); Mail::pretend(true); } public function tearDown() { parent::tearDown(); DB::statement('drop database coretest;'); } }
Причина, по которой вы получаете эту ошибку, просто потому, что laravel пытается подключиться к базе данных, указанной в config, которая не существует.
Решение состоит в том, чтобы создать собственное PDO-соединение из настроек без указания базы данных (PDO позволяет это) и запускать оператор CREATE DATABASE $dbname
используя его.
Мы использовали этот подход для тестирования в нашем проекте без каких-либо проблем.
Вот какой код:
<?php /** * Bootstrap file for (re)creating database before running tests * * You only need to put this file in "bootstrap" directory of the project * and change "bootstrap" phpunit parameter within "phpunit.xml" * from "bootstrap/autoload.php" to "bootstap/testing.php" */ $testEnvironment = 'testing'; $config = require("app/config/{$testEnvironment}/database.php"); extract($config['connections'][$config['default']]); $connection = new PDO("{$driver}:user={$username} password={$password}"); $connection->query("DROP DATABASE IF EXISTS ".$database); $connection->query("CREATE DATABASE ".$database); require_once('app/libraries/helpers.php'); // run migrations for packages foreach(glob('vendor/*/*', GLOB_ONLYDIR) as $package) { $packageName = substr($package, 7); // drop "vendor" prefix passthru("./artisan migrate --package={$packageName} --env={$testEnvironment}"); } passthru('./artisan migrate --env='.$testEnvironment); require('autoload.php'); // run laravel's original bootstap file
по<?php /** * Bootstrap file for (re)creating database before running tests * * You only need to put this file in "bootstrap" directory of the project * and change "bootstrap" phpunit parameter within "phpunit.xml" * from "bootstrap/autoload.php" to "bootstap/testing.php" */ $testEnvironment = 'testing'; $config = require("app/config/{$testEnvironment}/database.php"); extract($config['connections'][$config['default']]); $connection = new PDO("{$driver}:user={$username} password={$password}"); $connection->query("DROP DATABASE IF EXISTS ".$database); $connection->query("CREATE DATABASE ".$database); require_once('app/libraries/helpers.php'); // run migrations for packages foreach(glob('vendor/*/*', GLOB_ONLYDIR) as $package) { $packageName = substr($package, 7); // drop "vendor" prefix passthru("./artisan migrate --package={$packageName} --env={$testEnvironment}"); } passthru('./artisan migrate --env='.$testEnvironment); require('autoload.php'); // run laravel's original bootstap file
Я чувствую, что у меня есть более чистый способ сделать это. Просто выполняйте команды обычно через оболочку.
$host = Config::get('database.connections.mysql.host'); $database = Config::get('database.connections.mysql.database'); $username = Config::get('database.connections.mysql.username'); $password = Config::get('database.connections.mysql.password'); echo shell_exec('mysql -h ' . $host . ' -u ' . $username . ' -p' . $password . ' -e "DROP DATABASE ' . $database . '"'); echo shell_exec('mysql -h ' . $host . ' -u ' . $username . ' -p' . $password . ' -e "CREATE DATABASE ' . $database . '"');
neoascetic имеет лучший ответ, потому что по существу вам нужно снова загрузить файл конфигурации базы данных laravel.
Итак, умный взлом – это создать базу данных снова после того, как вы ее сбросили. Не нужно прикасаться к config / database.
public function setUp() { parent::setUp(); Artisan::call('migrate'); $this->seed(); Mail::pretend(true); } public function tearDown() { parent::tearDown(); DB::statement('drop database coretest;'); DB::statement('create database coretest;'); }
В Laravel 5 можно вызвать миграции внутри процесса Laravel, который заканчивается быстрее, чем использование внешних команд.
В TestCase :: setUp (или ранее) вызовите команду миграции с помощью:
$kernel = app('Illuminate\Contracts\Console\Kernel'); $kernel->call('migrate');