如何操作控制器测试的应用程序配置?

How to manipulate the application configs for controller tests?

我正在为 ZF3 应用程序(由 PHPUnit 和 zendframework/zend-test 驱动)编写功能/控制器测试。像这样:

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

它运行良好。但是现在我遇到了一个案例,我需要使用多个互斥的配置来测试应用程序。

例如案例"authentication":应用程序提供多种身份验证方法(假设:AuthAAuthBAuthC)。 (这可以通过在配置文件中设置 auth.type 的值来配置。)我想测试它们中的每一个。这意味着,在 /config/autoload/test/*{local|global}.php 中有特殊的测试配置是不够的。我需要能够为每个测试操纵它们(在我调用 dispatch(...) 方法之前)。

如何为/从控制器测试(动态)操作应用程序配置?


如果找不到更好的解决方案,可能的解决方法是在每次测试前编辑配置文件(通过使用 file_put_contents(...) 或类似的东西)。但是它有点难看(而且很慢)。

总的来说,我看不出这个问题有什么好的解决方案。但是有一些或多或少可以接受的解决方法:

解决方法 1:为每个测试操作相应的配置文件

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

这很费力并且会使测试变慢(由于从文件系统读取/写入文件系统)。

解决方法 2:只有一个配置值的简单文件

我们可以创建类似 config.auth.type.phpconfig.auth.type.txt 的文件(每个配置值一个,以保持文件非常简单)并使用 incluefile_get_contents(...) 调用作为值在配置中。文件中的值需要在测试执行前进行操作。

工作量少了一点(我们不需要编写复杂的 RegEx),但可能会使测试速度相当慢,因为 每个 应用程序请求都会从读取一个额外的开始文件。

解决方法 3:通过 GLOBALS

传递配置值

这是最简单、最快的变体。我们只需将所需的值保存到一个全局变量中,然后在配置(文件)数组中读取它。测试后我们去掉变量:

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',
    ],
];