PHPUnit - 将代码分解为可测试的块

时间:2013-02-20 15:43:05

标签: php tdd phpunit

我在某处读到,将方法分解为较小的可测试函数是个好主意,以便可以测试较小的方法。但我对如何测试调用较小方法的方法感到困惑。这是一个例子:

class MyTestableClass
{
    public function myHugeFunction($list, array $list_filter_params)
    {
        // do a bunch of stuff, then...
        foreach($list as $item) {
            $this->subFunction($item);
        }
    }

    public function subFunction()
    {
        // do stuff for each item
    }
}

和测试类:

class MyTestableClassTest extends PHPUnit_Framework_TestCase
{
    public function testSubFunction
    {
        // This tests the smaller, bite-size method, which is good.
    }
    public function testMyHugeFunction
    {
        // this tests the parent function *and* the subFunction. I'm trying
        // to test *just* the parent function.
    }
}

我知道如何测试子功能,但由于我无法在同一个类中存根方法,因此我不知道如何测试父方法 。我想找到一种方法来以某种方式将子函数存根到只返回true。

您是否使用事件并存根事件类?这是我能想到的另一种方法,即在同一个类中调用另一个方法。

1 个答案:

答案 0 :(得分:1)

除了@fab在他的评论中所说的内容(你真的应该考虑它!),实际上你可以在SUT中存根/模拟方法。对于您的示例,构建您的SUT对象可能如下所示:

class MyTestableClassTest extends PHPUnit_Framework_TestCase
{
    public function testSubFunction
    {
        // This tests the smaller, bite-size method, which is good.
    }
    public function testMyHugeFunction
    {
        // first, prepare your arugments $list and $list_filter_params
        // (...)

        // Next build mock. The second argument means that you will mock ONLY subFunction method
        $this->sut = $this->getMock('Namespace\MyTestableClass', array('subFunction'));

        // now you can set your subFunction expectations:
        $this->sut->expects($this->exactly(count($list))
            ->with($this->anything()); // of course you can make this mock better, I'm just showing a case

        // start testing
        $this->sut->myHugeFunction($list, $list_filter_params);
    }
}
PS再次,正如@fab所说:如果你展示一个特定的案例,我相信你会从这里得到很多好的答案。