1

我有一个我们公司使用的自定义轻量级 PHP 框架。首先,我不希望建议使用第三方框架。我正在尝试为它编写单元测试,但我偶然发现了一个问题。我对单元测试比较陌生,但是大部分代码已经被覆盖了。

我有一个加载器类,它需要无法用类自动加载器加载的文件(例如配置文件)。它有一种后备系统,如果您没有指定要从中加载特定资源的模块,它将尝试根据当前模块进行猜测,然后是默认模块。这要求我(据我所知)在回退到默认值之前检查特定文件的存在。

我遇到的问题是为实际上不依赖于任何现有文件的类编写测试(这显然是可取的)。我已经阅读了有关虚拟文件系统和测试的信息,但是我无法了解如何利用它来解决我的问题。

我可以编写注入到此类中的文件系统的抽象,但是该类将遇到类似的问题。

在伪代码中:如果该模块中存在文件,则加载它;如果没有,则加载默认值。

非常感谢任何建议。

编辑:

这是代码的摘录:

class Base implements Loader {

...

protected function _include( $type, $name ){
    $identifier = $this->parseName($name);

    $path = '/'.$this->resource_types[$type]['directory'].'/'.$this->resource_types[$type]['file_prefix'].$identifier['name'].'.php';

    if( $identifier['module'] && is_file(Core::basePath().'/'.Constant::get('MODULE_PATH').'/'.$identifier['module'].$path) ){
        Core::requireRoot('/'.Constant::get('MODULE_PATH').'/'.$identifier['module'].$path);

    } else if( is_file(Core::basePath().'/'.Constant::get('CORE_PATH').$path) ){
        Core::requireRoot('/'.Constant::get('CORE_PATH').$path);

    } else {
        throw new Exceptions\Load(ucwords($type).' '.$name.' not found');
    }
}

....

}

这是一个非常低级的类,所以它有一些静态调用,基本上可以替代或包装原生 PHP 函数。Core::requireRoot只是原生require函数的一个包装器。 Constant::get是常量的自定义实现(替代define,然后直接使用常量)。请记住,我实际上并没有直接测试此方法。我有公共方法,例如loadHooks我实际上正在测试的在幕后调用此方法的方法。

4

1 回答 1

1

感谢@hek2mgl 和(在较小程度上)@deceze(他对我的静态调用是正确的),我有一个解决这个问题的方法。这不是我最初希望的那种解决方案,但我认为这是可以做到的最好的。开始。

根据@hek2mgl 在此处的建议(github.com/metashock/Jm_Autoloader),我将使用临时文件。我认为没有办法解决这个问题,即使使用文件系统抽象对象也是如此。也就是说,我使用一个文件系统抽象对象,将其注入到这个类中,因为它可以更容易地在其他上下文中重用临时文件替换。

我将删除该函数中的静态调用(我知道最好不要这样做,但很容易说服自己“这是一个如此低级的类,实际上并不重要”)。相反,我将为 CORE_PATH 和 MODULES_PATH 创建 getter 和 setter 方法,并恢复为对 require 的本机调用。这不需要使用新的文件系统对象来完成,但我认为它更干净、更灵活、耦合更松散。

于 2013-08-24T13:57:23.917 回答