适当要求单元测试

时间:2016-06-26 20:32:24

标签: php oop testing phpunit

我一直在为应用编写单元测试,并希望测试一个具有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();

我想知道这是否可以被视为正确的方法或应该使用其他技术/解决方案?

1 个答案:

答案 0 :(得分:1)

require语句从文件系统加载文件。由于它与基础设施交互,因此应进行集成测试而不是单元测试。但是,有一些方法可以从文件系统中解耦,因此您可以正确地对其进行单元测试。

整合测试

如果您决定为您的类编写集成测试,则可以通过构造函数参数使配置文件的路径可配置。通过这种方式,您可以通过"测试"配置文件包含您可以在测试中依赖的值。

单元测试

如果您决定编写单元测试,则需要将文件加载移出课堂。将配置文件的加载结果作为构造函数参数传递,或将文件加载委托给协作者(即ConfigLoader)。您可以在单元测试中存根ConfigLoaderConfigLoader的实现将非常简单,您将为其编写集成测试(只是为了查看文件是否已加载并返回数组)。

例如:

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类的职责纯粹与加载配置文件有关 - 集成测试它。如果还有更多内容 - 将文件加载责任提取到自己的类中。