我正在为ZF3应用程序编写功能/控制器测试(由PHPUnit和zendframework/zend-test
驱动)。像这样:
public function testWhatEver()
{
$this->dispatch('/');
$this->assertResponseStatusCode(Response::STATUS_CODE_200);
}
效果很好。但是现在我有了一个案例,我需要使用多个互斥的配置来测试应用程序。
例如,案例“身份验证”:该应用程序提供了多种身份验证方法(例如:AuthA
,AuthB
,AuthC
)。 (这可以通过在配置文件中设置auth.type
的值来配置。)我想测试每个。这意味着在/config/autoload/test/*{local|global}.php
中拥有特殊的测试配置是不够的。我需要能够对每个测试进行操作(在我调用dispatch(...)
方法之前)。
如何为控制器测试(动态)操作应用程序配置?
如果找不到更好的解决方案,则可能的解决方法可能是在每次测试之前编辑配置文件(使用file_put_contents(...)
或类似方法)。但这有点难看(而且很慢)。
总的来说,我认为没有很好的解决方案。但是有一些或多或少可以接受的解决方法:
解决方法1:为每个测试操纵相应的配置文件
$configs = file_get_contents(...)
searchByRegexAndManipulateConfigs(...)
file_put_contents(...)
这很费力,并且会使测试变慢(由于读取/写入文件系统)。
解决方法2:仅一个配置值的简单文件
我们可以创建类似config.auth.type.php
或config.auth.type.txt
的文件(每个配置值一个,使文件非常简单),并使用inclue
或file_get_contents(...)
调用作为配置中的值。在执行测试之前,需要对文件中的值进行操作。
这省力(我们不需要编写复杂的RegEx),但是可能会使测试变得相当慢,因为every应用程序请求将通过读取其他文件开始。
解决方法3:通过GLOBALS
传递配置值
这是最简单,最快的变体。我们只是将所需的值保存到全局变量中,然后在config(文件)数组中读取它。测试后,我们删除变量:
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',
],
];