适当的要求单元测试

Proper require unit test

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

我想知道这是否可以被视为正确的方法,或者应该使用其他 technique/solution?

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

集成测试

如果您决定为 class 编写集成测试,您可以通过构造函数参数使配置文件的路径可配置。通过这种方式,您将能够传递一个 "test" 配置文件,其中包含您可以在测试中依赖的值。

单元测试

如果您决定编写单元测试,则需要将文件加载移出 class。要么将加载配置文件的结果作为构造函数参数传递,要么将文件加载委托给协作者(即 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;
    }
}

选择哪种方法?

这取决于您要测试的配置 class 的职责(记住单一职责原则)。

如果配置 class 的职责纯粹与加载配置文件有关 - 对其进行集成测试。如果还有更多内容 - 将文件加载责任提取到它自己的 class.