3

我的静态方法要么是“helper”类型,例如convertToCamelCase(),要么是“get singleton”类型,例如getInstance()。不管怎样,我很高兴他们住在一个助手班。

辅助类需要被广泛使用,所以我将它加载到我的层超类型中。现在,据我所知,只要可以将帮助程序注入超类型,我就可以在测试我的代码时保持完全的灵活性(帮助程序类本身除外)。那有意义吗?还是我忽略了什么?

换个角度看……在我看来,测试代码的难度与调用静态方法的次数成正比,而不是与静态方法本身的实际数量成正比。通过将所有这些调用放入一个类(我的助手),并用模拟替换该类,我正在测试没有静态调用和相关问题的代码。

(我意识到我应该努力摆脱我的单身人士,但这将是一个长期项目)。

4

2 回答 2

1

对于严格来说是“convertToCamelCase”之类的辅助函数的静态类,我可能对该函数只有 100% 的覆盖率,然后将其视为“核心”函数,而不必担心在其他地方模拟它。无论如何,“convertToCamelCase”的模拟是什么..?如果你做太多单元测试,也许你的单元测试开始闻起来有点像集成测试,但在抽象一切和让你的应用程序不必要地复杂之间总是有一些权衡。

就单例而言,这很棘手,因为您的代码中通常有静态类的名称,因此将其与模拟对象交换以进行测试变得有问题。您可以做的一件事是,无论您在哪里进行静态方法调用,首先要重构以这种方式调用它们:

$instance = call_user_func('MyClass::getinstance');

然后,随着您增加测试覆盖率,您可以开始替换为:

$instance = call_user_func($this->myClassName . '::getinstance');

MyClass所以 - 一旦你有了它,你可以通过改变来换掉和模拟$this->myClassName. 您必须确保您也需要或动态地自动加载相关的 php 文件。

重构以使用抽象工厂模式将使事情更容易测试,但您也可以随着时间的推移开始实现它

于 2013-03-26T23:43:23.140 回答
0

但是,如果您需要在某处模拟静态类,则可以使用Mokalibrary来完成。这是示例:

class UsersController
{

    public function main()
    {
        return json_encode(User::find(1));
    }
}

这是您可以测试它的方法:

class UsersController
{
    private $_userClass;

    public function __construct($userClass = 'User')
    {
        $this->_userClass = $userClass;
    }

    public function find($id)
    {
        return json_encode($this->_userClass::find($id));
    }
}

class UsersControllerTest extends \PHPUnit_Framework_TestCase
{
    public function testMainReturnsUser()
    {
        $userClass = Moka::stubClass(null, ['::find' => 'USER']);
        $controller = new UsersController($userClass);
        $this->assertEquals('"USER"', $controller->find(1000));
    }

    public function testMainCallsFind()
    {
        $userClass = Moka::stubClass(null, ['::find' => 'USER']);
        $controller = new UsersController($userClass);
        $controller->find(1000);
        // check that `find` was called with 100
        $this->assertEquals([1000], $userClass::$moka->report('find')[0]);
    }
}
于 2016-07-10T03:39:07.323 回答