Lumen 8 not using .env.testing

Viewed 1625

I'm using Lumen 8. and I want to use the configuration inside .env.testing but it always read the configuration inside .env

tests/TestCase.php

<?php

use Dotenv\Dotenv;

abstract class TestCase extends Tests\Utilities\UnitTest\Testing\TestCase
{

    public static function setUpBeforeClass(): void
    {
        Dotenv::createImmutable(dirname(__DIR__), '.env.testing')->load();
    
        parent::setUpBeforeClass();
    }
  
    public function createApplication()
    {
        return require __DIR__ . '/../bootstrap/app.php';
    }
}

.env.testing

APP_ENV=testing
APP_DEBUG=false

DB_CONNECTION=mysql
DB_HOST=db_testing
DB_PORT=3307
DB_DATABASE=db_testing
DB_USERNAME=db_username
DB_PASSWORD=db_password

.env

APP_ENV=local
APP_DEBUG=false

DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3307
DB_DATABASE=db_local
DB_USERNAME=db_username
DB_PASSWORD=db_password

when I debug the testing file like dd(DB::connection()->getDatabaseName()); it returns db_local instead of db_testing

I don't want to add all my configuration inside phpunit.xml what is missing? what should I do?

3 Answers

You're loading your environment file into a new repository instance, but your lumen application has no idea that repository instance exists.

Next, when your bootstrap/app.php file runs, it'll create the repository instance loaded with your normal .env file that lumen knows how to use.

The cleanest solution is probably to remove your setUpBeforeClass() method and just update your bootstrap/app.php file to support loading different .env files.

One example:

$env = env('APP_ENV');
$file = '.env.'.$env;

// If the specific environment file doesn't exist, null out the $file variable.
if (!file_exists(dirname(__DIR__).'/'.$file)) {
    $file = null;
}

// Pass in the .env file to load. If no specific environment file
// should be loaded, the $file parameter should be null.
(new Laravel\Lumen\Bootstrap\LoadEnvironmentVariables(
    dirname(__DIR__),
    $file
))->bootstrap();

If you update your bootstrap/app.php file with this code, then you can have one environment variable specified in your phpunit.xml file to set the APP_ENV variable to testing. If you do that, the above code would load the .env.testing file.

NB: all theory based on reading code. untested.

It's quite interesting that lumen does not support dynamic enviroment file names after they removed artisan support, Link to the Issue

So basically you have to go manual mode

In your bootstrap.app file

// boostrap.php

(new Laravel\Lumen\Bootstrap\LoadEnvironmentVariables(
    \dirname(__DIR__),
))->bootstrap();
class LoadEnvironmentVariables
{
    protected $filePath;
    protected $fileName;

    // change the $name, i.e the env file name to your env file manually
    public function __construct($path, $name = null)
    {
        $this->filePath = $path;
        $this->fileName = $name;
    }
  ....

Here's another link which might help

Simplified version of @patricus answer:

Update your bootstrap/app.php with this changes:

$env_file = '.env.' . env('APP_ENV');

(new Laravel\Lumen\Bootstrap\LoadEnvironmentVariables(
    dirname(__DIR__), file_exists(dirname(__DIR__) . '/' . $env_file) ? $env_file : null
))->bootstrap();
Related