Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

TollerHovler's avatar

Tests breaks but app starts working when running "config:cache"

Hello! I am unsure where I am doing wrong here and would appreciate any help. I have been all around the internet not finding any reason it should be this hard to get working. I realize I must've missed some obvious detail somewhere but I can't find it.

The problem:

  1. First, I run my tests. They all succeed and everything looks well.
  2. I open my browser and look at my application, where I get an "SQLSTATE[HY000] [2002] Connection refused" error.
  3. I run "php artisan config:cache" and check the browser again, the application works fine. However now, when I run my tests, they all (the ones interacting with the database) fail.
  4. I run "php artisan config:clear" and I am back on square one, the tests work - but not the app.

What I have tried:

I have spent hours searching for an explanation and the reason I run the "config" commands is just a result of that search. This is my current setup:

.env

DB_CONNECTION=sqlite
DB_DATABASE=/path-to-db/database.sqlite

DB_TEST_DRIVER=sqlite
DB_TEST_DATABASE=:memory:

config/database.php

    'connections' => [

        'sqlite' => [
            'driver' => 'sqlite',
            'url' => env('DATABASE_URL'),
            'database' => env('DB_DATABASE', database_path('database.sqlite')),
            'prefix' => '',
            'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true),
        ],

        'testing' => [
            'driver' => env('DB_TEST_DRIVER'),
            'database' => env('DB_TEST_DATABASE'),
            'prefix' => '',
        ],
     // ...
     ],

phpunit.xml

    <php>
        <server name="APP_ENV" value="testing"/>
       //...
        <server name="DB_CONNECTION" value="testing" />
    </php>

I read a thread on stackoverflow suggesting that you should have multiple .env files and then run the config:cache command to switch between them. But that can't be -the- solution to this, right? Since Laravel writes in the documentation that it's "built with testing in mind" it should be easy to apply TDD without having the need to run separate commands constantly? Or have I misunderstood something terribly?

Many thanks for any input!

0 likes
28 replies
Sinnbeck's avatar

Just curious. Do you by any chance have $connection set on any models or ::connection() on any migrations?

Oh and is this path absolute? Like from the root of your computer

DB_DATABASE=/path-to-db/database.sqlite
TollerHovler's avatar

@sinnbeck Yes, the path is correct. I guess, when I run the migration and seeds everything looks fine in the browser, as expected.

Sinnbeck's avatar

Do you have a .env.testing file in you root directory by any chance?

Sti3bas's avatar

@tollerhovler @sinnbeck interesting.. I've just tried it with the fresh Laravel 6 app and it does the same.

public function testBasicTest()
{
   dd(config('database.default')); //sqlite
}

If you run php artisan config:cache:

public function testBasicTest()
{
   dd(config('database.default')); //mysql
}

phpunit.xml:

<server name="DB_CONNECTION" value="sqlite"/>
<server name="DB_DATABASE" value=":memory:"/>
Sinnbeck's avatar

@sti3bas Do you also get "SQLSTATE[HY000] [2002] Connection refused" error. when opening a browser after the test?

TollerHovler's avatar

I don't anymore. I did try it as per a thread here or StackOverflow - but I got the same issue. But that would require me to constantly run config:cache commands when switching right? The thought of that felt clumsy and didn't really make sense to me as -the- solution, so I didn't go very long down that road.

TollerHovler's avatar

When I open the browser after the tests are run and green; yes - that's when the error pops up. I need to run the config:cache to make the error disappear, but that will break the tests. Until I run config:clear, which resets it again. :(

Sti3bas's avatar

@tollerhovler can you check which database is used when you open the browser after running the tests?

dd(\DB::connection()->getConfig());
TollerHovler's avatar

@sti3bas honestly, I am not 100% sure why I run it. It was a suggestion somewhere on a similar issue and I tried it - and since it removed the error I thought it was a step on the right road...

Hmm, how would I go about doing that? ^^'

TollerHovler's avatar

@sti3bas Ah, thank you.

I get this at first:

array:15 [▼
  "driver" => "mysql"
  "host" => "127.0.0.1"
  "port" => "3306"
  "database" => "homestead"
  "username" => "homestead"
  "password" => "secret"
  "unix_socket" => ""
  "charset" => "utf8mb4"
  "collation" => "utf8mb4_unicode_ci"
  "prefix" => ""
  "prefix_indexes" => true
  "strict" => true
  "engine" => null
  "options" => []
  "name" => "mysql"
]

After cache command:

array:5 [▼
  "driver" => "sqlite"
  "database" => "/Applications/MAMP/htdocs/apsat/database/database.sqlite"
  "prefix" => ""
  "foreign_key_constraints" => true
  "name" => "sqlite"
]
Sti3bas's avatar

@tollerhovler hmm, so DB_CONNECTION in .env file is set to sqlite, but for some reason it switches to mysql after the tests? It seems like it doesn't read your .env file before you run config:cache.

I guess database.default config value is set to env('DB_CONNECTION', 'mysql'), right?

TollerHovler's avatar

@sti3bas It switches back to mysql after i run the config:clear, which makes the tests run fine again. Then it switches to the sqlite when I run config:cache, but not for the tests. I dropped the dd() into one of the tests and it actually shows this post-clear:

array:5 [
  "driver" => "sqlite"
  "database" => ":memory:"
  "prefix" => ""
  "foreign_key_constraints" => true
  "name" => "sqlite"
]

and this post-cache:

array:5 [
  "driver" => "sqlite"
  "database" => "/Applications/MAMP/htdocs/apsat/database/database.sqlite"
  "prefix" => ""
  "foreign_key_constraints" => true
  "name" => "sqlite"
]

So it seems it grabs the correct one first, but as soon as I run the cache-command, it no longer use the DB_TEST-vars, but the live one. >.>

Sti3bas's avatar

@tollerhovler that's expected behaviour, as fresh Laravel app does the same. But your problem is that it doesn't work in the browser when you run config:clear, right?

TollerHovler's avatar

@sti3bas Exactly, it does not work in the browser, but the tests are fine. As soon as I cache, it's the other way around. I would love to have both working. :>

Sti3bas's avatar

@tollerhovler if you run config:clear and run dd(env('DB_CONNECTION')); in the Tinker, what does it show?

Sti3bas's avatar

@tollerhovler yeah, it should return null, because the config is cached and it doesn't read .env file anymore.

Sti3bas's avatar

It switches back to mysql after i run the config:clear, which makes the tests run fine again.

@tollerhovler mysql?

TollerHovler's avatar

@sti3bas Yes, when I dropped the

dd(\DB::connection()->getConfig());

Into the controller, it showed this after clear:

array:15 [▼
  "driver" => "mysql"
  "host" => "127.0.0.1"
  "port" => "3306"
  "database" => "homestead"
  "username" => "homestead"
  "password" => "secret"
  "unix_socket" => ""
  "charset" => "utf8mb4"
  "collation" => "utf8mb4_unicode_ci"
  "prefix" => ""
  "prefix_indexes" => true
  "strict" => true
  "engine" => null
  "options" => []
  "name" => "mysql"
]

And this after cache:

array:5 [▼
  "driver" => "sqlite"
  "database" => "/Applications/MAMP/htdocs/apsat/database/database.sqlite"
  "prefix" => ""
  "foreign_key_constraints" => true
  "name" => "sqlite"
]

I have no idea where the mysql comes from. >.>

Sinnbeck's avatar

Any chance you can test the project on another pc?

Please or to participate in this conversation.