Phpunit:私有方法运行了多少次


Phpunit: how many times has a private method run?

class TestMe
{
    private function a ($a, $b)
    {
        return $a+$b;
    }
    private function b ($a, $b)
    {
        return $a*$b;
    }
    public function serial ($a, $b)
    {
        $this->a ($a,$b);
        $this->b ($a,$b);
    }

和测试:

public function testA()
{
    $ref = new ReflectionClass ('TestMe');
    $method = $classNameOrObject->getMethod('a');
    $method->setAccessible(true);
    $this->assertEquals (2, $method->invokeArgs (1,1));
}
public function testB()
{
    $ref = new ReflectionClass ('TestMe');
    $method = $classNameOrObject->getMethod('b');
    $method->setAccessible(true);
    $this->assertEquals (1, $method->invokeArgs (1,1));
}
public function testSerial()
{
    $sut = new TestMe();
    $sut->testB();
}

testSerial我想检查一次a()b()触发器:

$stub = $this->getMock ('TestMe', array('a', 'b'));
$stub->expects($this->once())->method('a');
$stub->expects($this->once())->method('b');

这现在是不可能的,因为私有方法不能被嘲笑。知道吗?我可以用ReflectionClass做到这一点,但它会使原始功能无法使用。

不要嘲笑私有方法。 甚至不要尝试测试它们。 它们是您不需要关心的类的详细信息。 你所关心的只是公共职能部门做什么。 在您的示例中,这实际上什么都没有(它调用两个返回值的方法,并且对它们不执行任何操作(。

但是,假设该方法减去这两个值。 所以函数看起来像这样:

public function serial ($a, $b)
{
    $c = $this->a ($a,$b);
    $d = $this->b ($a,$b);
    return $c - $d;
}

示例测试可能如下所示:

/**
 * @dataProvider dataSerial
 */
public function testSerial($a, $b, $exp) {
    $sut = new TestMe();
    $this->assertEquals($exp, $sut->serial($a, $b));
}
public function dataSerial() {
    return array(
        array(
            1,
            1,
            1
        ),
        array(
            2,
            3,
            5
        ),
    )
}

我所关心的只是函数串行返回(或执行(的内容。 我不在乎私人功能。 如果出于某种原因,您决定删除上述测试通过的私有函数。 或者,如果serial()中的额外功能被移动到新的私有函数中,则测试将通过。

指定调用私有函数会降低测试的可用性,并使重构代码更加困难。 重构不应更改功能,因此不应导致测试失败。 指定私有方法意味着您必须确定测试是否由于删除私有方法或引入了错误而失败。

如果你的私有函数非常复杂,你觉得它们需要单独测试。 这是一种代码异味,也许这些方法应该提取到它们自己的类中。