How to specify a different .env file for phpunit in Laravel 5?

前端 未结 10 2199
礼貌的吻别
礼貌的吻别 2020-12-29 05:25

I have a .env file containing my database connection details, as is normal for Laravel 5. I want to override these for testing, which I can do in phpunit.

相关标签:
10条回答
  • 2020-12-29 05:58

    You could override the .env file being used in your TestCase file, where the framework is booted for testing.

    More specific:

    tests/TestCase.php

    /**
     * Creates the application.
     *
     * @return \Illuminate\Foundation\Application
     */
    public function createApplication()
    {
        /* @var \Illuminate\Foundation\Application $app */
        $app = require __DIR__ . '/../bootstrap/app.php';
    
        $app->loadEnvironmentFrom('.env.testing'); // specify the file to use for environment, must be run before boostrap
    
        $app->make('Illuminate\Contracts\Console\Kernel')->bootstrap();
    
        return $app;
    }
    

    All the tests extending TestCase will use this configuration file.

    Please note that any setting defined in phpunit.xml will override this configuration.

    Update

    Starting Laravel5.4, the createApplication function is no longer found in tests\TestCase. It has been moved to tests\CreatesApplication trait.

    0 讨论(0)
  • 2020-12-29 05:58

    Create a local database on your dev machine, e.g. 'local_test_db'

    Create a new .env.testing file.

    DB_DATABASE=local_test_db
    DB_USERNAME=root
    

    Make sure your phpunit.xml file has at least this one env var:

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

    Lastly your base testcase (TestCase.php) should run a migration to populate the db with tables:

    public function createApplication()
    {
    
        $app = require __DIR__.'/../bootstrap/app.php';
    
        $app->make(Illuminate\Contracts\Console\Kernel::class)->bootstrap();
    
        return $app;
    }
    
    
    public function setUp()
    {
        parent::setUp();
        Artisan::call('migrate');
    }
    
    public function tearDown()
    {
        Artisan::call('migrate:reset');
        parent::tearDown();
    }
    
    0 讨论(0)
  • 2020-12-29 05:59

    This is 2019.

    I had this issues for so long until I was able to figure it out.

    And here is my assumption:

    If you are also finding it difficult to make your PHPUnit.xml talk with your .env.testing file, then you are likely using PHPStorm!

    If this is true, continue reading.

    If not, nope...this won't help.

    Ok...

    Here you go:

    1. Go to Settings of your PHPStorm or just simply press Ctrl + Alt + S.
    2. Go to Languages And Frameworks >> PHP >> Test Frameworks
    3. Under Test Runner tab, click Default configuration file and select (by clicking the folder icon) the path of your project's PHPUnit.xml file.

    What this does is to make all your changes in the xml file take effect. So, go ahead, create the .env.testing file, create your preferred DB config variables for test...and try running your tests again!

    0 讨论(0)
  • 2020-12-29 06:05

    From this link

    Method 1

    Step 1: Create New Test Database Connection on Database/Config.php as below:

    return [
        ... 
    
        'default' => env('DB_CONNECTION', 'db'),    
    
        'connections' => [
            'sqlite_testing_db' => [
                'driver' => 'sqlite',
                'database' => storage_path().'/testing_database.sqlite',           
                'prefix' => '',
            ],
    
            /**************** OR ******************/
    
            'testing_db' => [
                'driver' => 'mysql',
                'host' => env('TEST_DB_HOST', 'localhost'),
                'database' => env('TEST_DB_DATABASE', 'forge'),
                'username' => env('TEST_DB_USERNAME', 'forge'),
                'password' => env('TEST_DB_PASSWORD', ''),
                'charset' => 'utf8',
                'collation' => 'utf8_unicode_ci',
                'prefix' => '',
                'strict' => false,
            ],
    
            /** Production or database DB **/
            'db' => [
                'driver' => 'mysql',
                'host' => env('TEST_DB_HOST', 'localhost'),
                'database' => env('TEST_DB_DATABASE', 'forge'),
                'username' => env('TEST_DB_USERNAME', 'forge'),
                'password' => env('TEST_DB_PASSWORD', ''),
                'charset' => 'utf8',
                'collation' => 'utf8_unicode_ci',
                'prefix' => '',
                'strict' => false,
            ],
        ],
    ];
    

    Step 2: Specify the Database Credential on .env file

    TEST_DB_HOST=localhost
    TEST_DB_DATABASE=laravel
    TEST_DB_USERNAME=root
    TEST_DB_PASSWORD=rootwdp
    

    Step 3: Specify test db conection to be used on phpunit.xml.

    <env name="DB_CONNECTION" value="testing_db"/>
              OR Below If you prefer sqlite
    <env name="DB_CONNECTION" value="sqlite_testing_db"/>                
    

    Step 4: Migrate database to this new testing database - if you choose to use Database Transaction to Rollback insertion on the table.

    php artisan migrate --database=testing_db
    
    //If using sqlite
    touch storage/testing_database.sqlite
    php artisan migrate --database=sqlite_testing
    

    Step 5: Now, the Unit test with Database Transaction looks like below:

    <?php
    
    use App\User;
    use Illuminate\Foundation\Testing\DatabaseTransactions;
    
    class UserTest extends TestCase
    {
        use DatabaseTransactions;
    
        /** @test */
        function it_test_user_can_be_saved()
        {
            factory(User::class, 2)->create();
    
            $users = User::all();
    
            $this->assertEquals(2, $users->count());
        }
    }
    
    //Run Php Unit
    -> vendor/bin/phpunit --color tests/acceptance/model/UserTest.php
    

    Note: If you prefer not to use Database Transaction, you can use setup and teardown method on TestCase.php class to migrate and rollback the database as below:

    <?php
    
    use Illuminate\Support\Facades\Artisan;
    
    class TestCase extends Illuminate\Foundation\Testing\TestCase
    {
        ...
    
        public function setUp()
        {
            parent::setUp();
            Artisan::call('migrate');
        }
    
        public function tearDown()
        {
            Artisan::call('migrate:reset');
            parent::tearDown();
        }
    }
    
    0 讨论(0)
  • 2020-12-29 06:05

    In your app.php change the Dotenv section

    $envFile = 'testing' === env('APP_ENV') ? '.env.testing' : null;
    try {
        (new Dotenv\Dotenv(__DIR__ . '/../', $envFile))->load();
    } catch (Dotenv\Exception\InvalidPathException $e) {
        //
    }
    

    This will work hence PHPUnit changes the env before loading your app..so if running tests you will have the env already at testing

    0 讨论(0)
  • 2020-12-29 06:08

    I can't think of a way other than temporarily renaming .env.testing to .env before the unit tests start.

    You could put some logic in bootstrap/autoload.php as this is what phpunit uses as it's bootstrap file before loading the application.

    0 讨论(0)
提交回复
热议问题