Laravel creates a database when testing

I am trying to run my unit test and create a database during installation. For some reason, I get an Unknown database 'coretest' error message. If I create a database, although I manually run the test, I get Can't create database 'coretest'; database exists Can't create database 'coretest'; database exists .

The drop database statement now only works with the create database.

Here are my setUP and tearDown methods:

 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;'); } } 
+9
php laravel laravel-4
source share
4 answers

The reason you get this error is simply because laravel is trying to connect to the database specified in config, which does not exist.

The solution is to create your own PDO connection from the settings without specifying a database (PDO allows this) and run the CREATE DATABASE $dbname statement using it.

We used this approach for testing in our project without any problems.


Here is some 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 original bootstap file 
+11
source share

neoascetic has a better answer, because essentially you need to download the laravel database configuration file again.

So, smart hacking is to create the database again after you reset 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;'); } 
+2
source share

I feel like I have a cleaner way to do this. Just execute the commands usually through the 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 . '"'); 
+1
source share

In Laravel 5, you can trigger a migration inside the Laravel process, which finishes with a good bit faster than using external commands.

In TestCase :: setUp (or earlier), invoke the migration command with:

 $kernel = app('Illuminate\Contracts\Console\Kernel'); $kernel->call('migrate'); 
0
source share

All Articles