如何操作控制器测试的应用程序配置?
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":应用程序提供多种身份验证方法(假设: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),但可能会使测试速度相当慢,因为 每个 应用程序请求都会从读取一个额外的开始文件。
解决方法 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',
],
];
我正在为 ZF3 应用程序(由 PHPUnit 和 zendframework/zend-test
驱动)编写功能/控制器测试。像这样:
public function testWhatEver()
{
$this->dispatch('/');
$this->assertResponseStatusCode(Response::STATUS_CODE_200);
}
它运行良好。但是现在我遇到了一个案例,我需要使用多个互斥的配置来测试应用程序。
例如案例"authentication":应用程序提供多种身份验证方法(假设: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),但可能会使测试速度相当慢,因为 每个 应用程序请求都会从读取一个额外的开始文件。
解决方法 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',
],
];