我一直在为应用编写单元测试,并希望测试一个具有require
的方法。我看待它的方式
public $configPath = __DIR__.'/path/to/config.php';
private function getConfig()
{
if (!empty($this->config)) {
return $this->config;
}
return $this->config = require $this->configPath;
}
public method foo()
{
$config = $this->getConfig();
//logic here
}
在测试用例中,相应的代码段是
$class->config = ['bar' => 'baz'];
$class->foo();
我想知道这是否可以被视为正确的方法或应该使用其他技术/解决方案?
答案 0 :(得分:1)
require
语句从文件系统加载文件。由于它与基础设施交互,因此应进行集成测试而不是单元测试。但是,有一些方法可以从文件系统中解耦,因此您可以正确地对其进行单元测试。
整合测试
如果您决定为您的类编写集成测试,则可以通过构造函数参数使配置文件的路径可配置。通过这种方式,您可以通过"测试"配置文件包含您可以在测试中依赖的值。
单元测试
如果您决定编写单元测试,则需要将文件加载移出课堂。将配置文件的加载结果作为构造函数参数传递,或将文件加载委托给协作者(即ConfigLoader
)。您可以在单元测试中存根ConfigLoader
。 ConfigLoader
的实现将非常简单,您将为其编写集成测试(只是为了查看文件是否已加载并返回数组)。
例如:
class ConfigLoader
{
public function load($file)
{
$config = require $file;
if (!is_array($config)) {
throw new InvalidConfigFileException(sprintf('Did not find configuration in "%s".', $file));
}
return $config;
}
}
选择哪种方法?
这取决于您尝试测试的配置类的责任(记住单一责任原则)。
如果config类的职责纯粹与加载配置文件有关 - 集成测试它。如果还有更多内容 - 将文件加载责任提取到自己的类中。