Get Config in Routes tested?

725 Views Asked by At

I need to make my routes conditional, based on config:

//routes/auth.php

if (config('auth.allow_registration')) {....

The above config param is set in the config file:

//config/auth.php

'allow_registration' => false,

It is all working fine, until I try to unit-test it

public function test_registration_screen_can_be_rendered()
{
    config()->set('auth.allow_registration', true);
    $response = $this->get('/register');

    $response->assertStatus(200);
}

The test case is failing.

I understand that after I change config, I need to reread routes. But how?

I found only this $this->refreshApplication(); it suppose to reread routes, but it also rereads the config.

How can I only reread routes, but keep my modified config intact?

2

There are 2 best solutions below

2
On

You can use a middleware on routes witch you want to have conditions for access. then you can just use the middleware on the route or in your controller. you can learn about it in Laravel good documentation here.

2
On

If you change that config parameter's value to be read from an environment variable, then you can override it for a given test class in the setUp() method. When Laravel reads the config, it will first check if there's an environment variable for the value, then fall back on the default if not.

// config/auth.php

'allow_registration' => env('ALLOW_REGISTRATION', false),
// tests/feature/RegistrationEnabledTest.php

namespace Tests\Feature;

use Tests\TestCase;

class RegistrationEnabledTest extends TestCase
{
    protected function setUp(): void
    {
        putenv("ALLOW_REGISTRATION=true");
        parent::setup();
    }

    public function test_registration_screen_can_be_rendered()
    {
        $response = $this->get('/register');

        $response->assertStatus(200);
    }
}

If you'd like to set it for all of your tests, you can add it to your phpunit.xml in the php environment section:

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

Unfortunately, setting an env only works for either all tests or a given test class, I also couldn't find a way to get it to work for just a single test within a test class ($this->refreshApplication() doesn't seem to respect the env change), and manually changing routes at runtime is not something Laravel is designed for. However, I think it's a reasonable workaround to separate out tests of various config settings into discrete test classes.