trip.somers's avatar

Is it possible to mock the application's environment?

I have a piece of middleware (in Lumen) that looks like this:

    if ((app()->environment('production') && $request_mode != 'production') ||
        (! app()->environment('production') && $request_mode != 'development'))
    {
        throw new MismatchedModeException();
    }

This is an extra layer of protection (beyond an API token for authentication and an IP whitelist -- we're thorough) to make sure that a specific request mode is used based on the environment that receives the request.

The problem I have is that when running tests on the project, the environment is always 'testing', making it impossible for me to accurately test this middleware for proper handling of 'production' requests.

I have tried a number of methods that have all failed:

  • PHPUnit::createMock(Application::class, ['environment']) -- Mocked 'environment()' calls fail to use mocked responses (tried many variations of will() and willReturn())

  • Instantiation of "mini-app" inside test -- didn't allow us to do anything we couldn't do on the full app itself.

  • putenv('APP_ENV=production') -- seems to be the most direct, but it stalls phpunit when using expectException()

I figure I can't be the first person to have something like this, so I'm reaching to see if anyone else has successfully accomplished what I'm trying to do.

0 likes
1 reply
trip.somers's avatar

Here's an example test method that attempts to make sure the exception is thrown when someone sends a 'development' request to the 'production' environment:

    public function testInvalidDevelopmentMode()
    {
        // fake production environment
        putenv('APP_ENV=production');

        $request = new Request();
        $request->headers->add([
            'mode' => 'development'
        ]);

        $next = function($val) {
            return $val;
        };

        $this->expectException(MismatchedModeException::class);

        $response = (new RequestModeMiddleware)->handle(
            $request, $next, 'testEndpoint'
        );

/* phpunit hangs here after the exception is logged to lumen.log */

        // restore testing environment
        putenv('APP_ENV=testing');
    }

Please or to participate in this conversation.