How to manipulate the application configs for controller tests?

53 Views Asked by At

I'm writing functional / controller tests for a ZF3 application (driven by PHPUnit and zendframework/zend-test). Like this:

public function testWhatEver()
{
    $this->dispatch('/');
    $this->assertResponseStatusCode(Response::STATUS_CODE_200);
}

It's working pretty well. But now I got a case, where I need to test the application with multiple mutually exclusive configs.

E.g., the case "authentication": The application provides multiple authentication methods (let's say: AuthA, AuthB,AuthC). (That is configurable via setting of the auth.type's value in the config file.) I want to test each of them. That means, it's not enough to have special test configs in the /config/autoload/test/*{local|global}.php. I need to be able to manipulate them for every test (before I call the dispatch(...) method).

How to manipulate the application configs for / from controller tests (on the fly)?


If no better solution can be found, a possible workaround might be to edit the config file (by using file_put_contents(...) or something like this) before every test. But it's a bit ugly (and slow).

1

There are 1 best solutions below

0
On BEST ANSWER

In general I see no really nice solution for this problem. But there some more or less acceptable workaround:

Workaround 1: manipulating the according config file for every test

  1. $configs = file_get_contents(...)
  2. searchByRegexAndManipulateConfigs(...)
  3. file_put_contents(...)

It's much effort and would make the testing slower (due to reading from / writing to the filesystem).

Workaround 2: simple files with only one config value

We can create files like config.auth.type.php or config.auth.type.txt (one per config value t keep the file really simple) and to use inclue or file_get_contents(...) call as value in the config. The the value in the file needs to be manipulated before the test execution.

It's a bit less effort (we don't need to write complex RegEx), but might make the test considerably slower, since every application request would start by reading an additional file.

Workaround 3: passing configs values through GLOBALS

It's the simplest and fastest variant. We just save the needed value into a global variable and read it in the config (file's) array. After the test we remove the variable:

AuthBTest

...
protected function setUp() // or setUpBeforeClass()
{
    parent::setUp();
    $GLOBALS['appTestConfigs']['auth.type'] = 'AuthA';
}

protected function tearDown() // or tearDownAfterClass()
{
    parent::tearDown();
    unset($GLOBALS['appTestConfigs']);
}
...

/config/autoload/test/local.php

return [
    'auth' => [
        'type' => isset($GLOBALS['appTestConfigs']['auth.type']) ? $GLOBALS['appTestConfigs']['auth.type'] : 'AuthA',
    ],
];