Search code examples
databaselaravellaravel-5phpunitlaravel-5.3

Laravel - Modify DB::connection method


I want to modify DB::connection so if I am running tests it will override a given connection.

I have lots of hard-coded connections in the models like this DB::connection('mysql2') so I want to override the mysql2 connection with mysql_testing.

How can I go about this?


Solution

  • What I usually do is adding in phpunit.xml:

    <env name="DB_CONNECTION" value="mysql_testing"/>
    

    Then in config/database.php I create duplicate of mysql connection something like this:

    'mysql_testing' => [
        'driver' => 'mysql',
        'host' => env('DB_TESTING_HOST', 'localhost'),
        'database' => env('DB_TESTING_DATABASE', 'forge'),
        'username' => env('DB_TESTING_USERNAME', 'forge'),
        'password' => env('DB_TESTING_PASSWORD', ''),
        'charset' => 'utf8',
        'collation' => 'utf8_unicode_ci',
        'prefix' => '',
        'strict' => false,
    ],
    

    and then in .env I define testing connection settings:

    #TESTING
    
    DB_TESTING_HOST=127.0.0.1
    DB_TESTING_DATABASE=test_database
    DB_TESTING_USERNAME=root
    DB_TESTING_PASSWORD=pass
    

    It's working without any problems plus you don't need to switch anything in .env if you are running tests and testing application manually on same machine/in same directory

    EDIT

    If you have situation like this, probably modifying multiple models is not the best way but if you want to use same database regardless of connection set you can do something like that:

    Assuming you have set environment to testing what can be done using:

    <env name="APP_ENV" value="testing"/>
    

    in your phpunit.xml file you can do go into your AppServiceProvider class and in register method do something like this:

    if ($this->app->environment('testing')) {
        $this->app['config']->set('database.connections.mysql2.database', 'yourcustom testing database');
        // ... 
        $this->app['config']->set('database.connections.mysql15.database', 'yourcustom testing database');
    }
    

    I haven't tried it but it should work - it should make that when running tests you can set all your connections to same testing database (or to other databases if you wish)