2013-06-28 11 views
8

Próbuję uruchomić mój test jednostki i utworzyć bazę danych podczas instalacji. Z jakiegoś powodu otrzymuję komunikat o błędzie Unknown database 'coretest'. Jeśli utworzę bazę danych ręcznie i uruchomię test, otrzymam Can't create database 'coretest'; database exists.Laravel utworzyć bazę danych podczas testowania

Instrukcja opuszczania bazy danych działa właśnie w tej bazie danych.

Oto moje ustawienia i przerywaniem metody:

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

Odpowiedz

10

Powodem dlaczego masz ten błąd jest po prostu dlatego, laravel próbuje połączyć się z bazą danych określonych w konfiguracji, która nie istnieje.

Rozwiązaniem jest zbudowanie własnego połączenia PDO z ustawień bez określania bazy danych (pozwala to na to PDO) i użycie instrukcji CREATE DATABASE $dbname.

Zastosowaliśmy to podejście do testowania w naszym projekcie bez żadnego problemu.


Here jakiś kod:

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

Czy to rozwiązanie zadziałałoby dla Laravel 5? a jeśli tak, wszelkie komentarze do niego. thx;) –

1

czuję się jakbym miał znacznie czystszy sposób to robi. Po prostu wykonuj polecenia normalnie przez powłokę.

$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

W laravel 5 to możliwe, aby wywołać migracje wewnętrzne w procesie laravel która kończy się działa sporo szybciej niż przy użyciu poleceń zewnętrznych.

W TestCase :: Setup (lub wcześniej), należy wywołać komendę migracji z:

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

Dlaczego po prostu nie użyć cechy '\ Illuminate \ Foundation \ Testing \ DatabaseMigrations'? – Pablo

2

neoascetic ma najlepszą odpowiedź, bo w zasadzie trzeba ponownie uruchomić plik konfiguracyjny bazy danych laravel użytkownika.

Zatem sprytnym hackiem jest ponowne utworzenie bazy danych po jej upuszczeniu. Nie trzeba dotykać konfiguracji/bazy danych.

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;'); 
} 
Powiązane problemy