2013-06-28 3 views
8

Я пытаюсь запустить мой модульный тест и создать базу данных во время установки. По какой-то причине я получаю ошибку Unknown database 'coretest'. Если я создам базу данных, но вручную и запустил тест, то получаю Can't create database 'coretest'; database exists.Laravel создать базу данных при тестировании

Оператор базы данных drop работает только с созданием базы данных.

Вот моя установка и демонтаж метода:

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;'); 
    } 
} 

ответ

10

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

Решение состоит в том, чтобы создать собственное PDO-соединение из настроек без указания базы данных (PDO разрешает это) и запустить с помощью нее CREATE DATABASE $dbname.

Мы использовали этот подход для тестирования в нашем проекте без каких-либо проблем.


Here некоторый код:

<?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 
+0

будет ли это решение работать на Laravel 5? и если да, то любые комментарии к нему. thx;) –

1

Я чувствую, что у меня есть более простой способ сделать это. Просто выполняйте команды обычно через оболочку.

$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 . '"'); 
0

В Laravel 5, что можно назвать миграции внутри страны к процессу Laravel который заканчивается работает хороший немного быстрее, чем при использовании внешних команд.

В TestCase :: нАлАдкА (или ранее), вызовите команду миграции с:

$kernel = app('Illuminate\Contracts\Console\Kernel'); 
$kernel->call('migrate'); 
+2

Почему бы просто не использовать черту '\ Illuminate \ Foundation \ Testing \ DatabaseMigrations'? – Pablo

2

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;'); 
}