2013-06-28 11 views
8

Tôi đang cố chạy thử nghiệm đơn vị của mình và tạo cơ sở dữ liệu trong khi thiết lập. Vì một lý do nào đó, tôi gặp lỗi Unknown database 'coretest'. Nếu tôi tạo cơ sở dữ liệu mặc dù bằng tay và chạy thử nghiệm thì tôi nhận được Can't create database 'coretest'; database exists.Laravel tạo cơ sở dữ liệu khi thử nghiệm

Tuyên bố cơ sở dữ liệu thả hoạt động ngay bây giờ tạo cơ sở dữ liệu.

Đây là thiết lập và teardown tôi phương pháp:

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

Trả lời

10

Lý do tại sao bạn nhận được lỗi này chỉ đơn giản là vì laravel cố gắng để kết nối với cơ sở dữ liệu quy định trong cấu hình, mà không tồn tại.

Giải pháp là xây dựng kết nối PDO của riêng bạn từ cài đặt mà không chỉ định cơ sở dữ liệu (PDO cho phép điều này) và chạy câu lệnh CREATE DATABASE $dbname sử dụng nó.

Chúng tôi đã sử dụng phương pháp này để thử nghiệm trong dự án của mình mà không gặp bất kỳ sự cố nào.


Here một số mã:

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

giải pháp này có hiệu quả với Laravel 5 không? và nếu có thì có ý kiến ​​gì. thx;) –

1

Tôi cảm thấy như tôi có một cách sạch hơn để làm điều này. Chỉ cần thực hiện các lệnh thông thường thông qua trình bao.

$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

Trong Laravel 5, bạn có thể gọi di chuyển nội bộ đến quá trình Laravel chạy nhanh hơn một chút so với sử dụng các lệnh bên ngoài.

Trong TestCase :: thiết lập (hoặc sớm hơn), gọi lệnh di chuyển với:

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

Tại sao không chỉ sử dụng đặc điểm '\ Illuminate \ Foundation \ Testing \ DatabaseMigrations'? – Pablo

2

neoascetic có câu trả lời tốt nhất bởi vì về cơ bản bạn phải khởi động tập tin cấu hình cơ sở dữ liệu laravel một lần nữa.

Vì vậy, thông minh là tạo lại cơ sở dữ liệu sau khi bạn đã xóa nó. Không cần phải chạm vào cấu hình/cơ sở dữ liệu.

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