Lzh on GitHub

大型父类

在某些应用程序代码中,尤其是较旧的遗留代码,我们可能会遇到一些类继承自一个 “大型父类”——一个既全能又做了太多事情的父类:

在某些应用程序代码中,尤其是较旧的遗留代码,我们可能会遇到一些类继承自一个 “大型父类”——一个既全能又做了太多事情的父类:

class BigParentClass
{
    public function doesEverything()
    {
        // 设置数据库连接
        // 写入日志文件
    }
}

class ChildClass extends BigParentClass
{
    public function doesOneThing()
    {
        // 但会调用 BigParentClass 的方法
        $result = $this->doesEverything();
        // 对 $result 做些什么
        return $result;
    }
}

我们想要测试我们的 ChildClass 及其 doesOneThing 方法,但问题在于它会调用 BigParentClass::doesEverything()。处理这个问题的一种方法是模拟 BigParentClass 所有 的依赖项和需求,然后最终实际测试我们的 doesOneThing 方法。这样做工作量太大了。

我们可以做一些……不寻常的事情。我们可以为 ChildClass 本身创建一个 运行时部分测试替身,并仅模拟父类的 doesEverything() 方法:

$childClass = \Mockery::mock('ChildClass')->makePartial();
$childClass->shouldReceive('doesEverything')
    ->andReturn('some result from parent');
$childClass->doesOneThing(); // string("some result from parent");

通过这种方法,我们只模拟了 doesEverything() 方法,而所有未被模拟的方法都会在实际的 ChildClass 实例上被调用。