Chill's avatar
Level 7

Why are .env settings overwriting phpunit.xml settings?

My database.php looks like this:

    'default' => env('DB_CONNECTION', 'production'),

    'connections' => [

        'tests' => [
            'driver'   => 'sqlite',
            'database' => env('DB_DATABASE', database_path('database.sqlite')),
            'prefix'   => '',
        ],

        'production' => [
            'driver'    => 'mysql',
            // etc, etc
        ],

In my .env I am setting:

DB_HOST=localhost
DB_DATABASE=my_production_database
DB_USERNAME=my_user
DB_PASSWORD=my_pass

And finally, in my phpunit.xml file:

    <php>
        <env name="APP_ENV" value="testing"/>
        <env name="CACHE_DRIVER" value="array"/>
        <env name="SESSION_DRIVER" value="array"/>
        <env name="QUEUE_DRIVER" value="sync"/>
        <env name="DB_CONNECTION" value="tests"/>
    </php>

I created the sqlite file touch database/database.sqlite and then I ran php artisan migrate --database=tests and it performed the four migrations I have setup. I double checked by opening the sqlite file a sqlite explorer and all the migration tables are there.

The trouble comes as I'm running phpunit. When I call a factory for one of my models, I get the following exception thrown: InvalidArgumentException: Database (my_production_database) does not exist. This is odd since the only place that string exists is in my .env file and I specifically set DB_CONNECTION to tests in phpunit.xml.

Just for kicks I completely remove everything DB related from .env. Now the error becomes: Illuminate\Database\QueryException: SQLSTATE[3D000]: Invalid catalog name: 1046 No database selected

What's going on? I'd like to have sqlite for testing and my regular mysql db for production.

0 likes
5 replies
ejdelmonico's avatar

phpunit.xml file should be:

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

and .env should be:

    DB_CONNECTION=sqlite

I would try that. Also, you should leave database config using the default mysql for the ENV variable so when you move to production...you don't have to use a .env variable for the database.

    'default' => env('DB_CONNECTION', 'mysql'),

    ...

    'connections' => [
        'sqlite' => [
            'driver' => 'sqlite',
            'database' => env('DB_DATABASE', database_path('database.sqlite')),
            'prefix' => '',
        ],
        'mysql' => [
            'driver' => 'mysql',
            'host' => env('DB_HOST', 'localhost'),
            'port' => env('DB_PORT', '3306'),
            'database' => env('DB_DATABASE', 'forge'),
            'username' => env('DB_USERNAME', 'forge'),
            'password' => env('DB_PASSWORD', ''),
            'charset' => 'utf8',
            'collation' => 'utf8_unicode_ci',
            'prefix' => '',
            'strict' => true,
            'engine' => null,
        ],

    ....

Chill's avatar
Level 7

@ejdelmonico I think the formatting on your post got somehow corrupted and I can't quite make sense of it. Would you mind taking a look at it? (and of course, thanks for taking the time to answer!)

Chill's avatar
Level 7

OK, I see what you mean. I did try that and the error is exactly the same: Invalid catalog name: 1046 No database selected

Still, I wouldn't want to be changing my .env just for running tests. Seems incredibly cumbersome having to change this file 100 times per day.

Chill's avatar
Level 7

OK I found the root of the problem!

The model classes had the protected member $connection set to the production DB. As I removed this member, the tests started working perfectly.

1 like

Please or to participate in this conversation.