Laravel create database when testing

后端 未结 4 1494
清歌不尽
清歌不尽 2021-01-02 05:35

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 databa

相关标签:
4条回答
  • 2021-01-02 06:00

    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.

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

    $kernel = app('Illuminate\Contracts\Console\Kernel');
    $kernel->call('migrate');
    
    0 讨论(0)
  • 2021-01-02 06:07

    The reason why you get this error is simply because laravel tries to connect to database specified in config, which doesn't exist.

    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.

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


    Here 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's original bootstap file
    
    0 讨论(0)
  • 2021-01-02 06:08

    I feel like I have a much cleaner way of doing this. Just execute the commands normally 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 . '"');
    
    0 讨论(0)
  • 2021-01-02 06:09

    neoascetic has the best answer because essentially you have to boot laravel's database config file again.

    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;');
    }
    
    0 讨论(0)
提交回复
热议问题