Laravel 测试时创建数据库
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17373557/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Laravel create database when testing
提问by ipengineer
I am trying to run my unit test and create a database during setup. For some reason I am getting the error Unknown database 'coretest'
. If I create the database though manually and run the test then I get Can't create database 'coretest'; database exists
.
我正在尝试运行我的单元测试并在安装过程中创建一个数据库。出于某种原因,我收到了错误Unknown database 'coretest'
。如果我手动创建数据库并运行测试,那么我会得到Can't create database 'coretest'; database exists
.
The drop database statement works just now the create database.
drop database 语句现在对create database 起作用。
Here is my setUP and tearDown methods:
这是我的 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;');
}
}
回答by neoascetic
The reason why you get this error is simply because laravel tries to connect to database specified in config, which doesn't exist.
您收到此错误的原因仅仅是因为 laravel 尝试连接到配置中指定的数据库,而该数据库不存在。
The solution is to build your own PDO connection from the settings without specifying database (PDO allows this) and run CREATE DATABASE $dbname
statement using it.
解决方案是从设置中构建您自己的 PDO 连接而不指定数据库(PDO 允许这样做)并CREATE DATABASE $dbname
使用它运行语句。
We used this approach for testing in our project without any problem.
我们在我们的项目中使用这种方法进行测试没有任何问题。
Heresome code:
这里有一些代码:
<?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
回答by Ryan Boyd
neoascetic has the best answer because essentially you have to boot laravel's database config file again.
Neoascetic 有最好的答案,因为基本上你必须再次启动 laravel 的数据库配置文件。
So, a clever hack is to create database again after you have dropped it. No need to touch 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;');
}
回答by Leng
I feel like I have a much cleaner way of doing this. Just execute the commands normally through the shell.
我觉得我有一个更清洁的方法来做到这一点。只需通过shell正常执行命令即可。
$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 . '"');
回答by Israel Zion Shirk
In Laravel 5 it's possible to call migrations internally to the Laravel process which ends up running a good bit quicker than using external commands.
在 Laravel 5 中,可以在内部调用 Laravel 进程的迁移,最终运行速度比使用外部命令快得多。
In TestCase::setUp (or earlier), call the migration command with:
在 TestCase::setUp(或更早版本)中,使用以下命令调用迁移命令:
$kernel = app('Illuminate\Contracts\Console\Kernel');
$kernel->call('migrate');