2

我想测试这个功能:

public function reset()
{
    if(!$this->onBeforeReset())      // Protected, internal method
    {
         return false;
    }

    // Continue with tests
}

我也希望在onBeforeReset函数返回 false 或 true 时对其进行测试。
我怎样才能做到这一点?那可能吗?
有没有办法“模拟”被测类的某些部分?

4

2 回答 2

2

是的,除非您要模拟的方法是私有的或最终的,否则您可以只模拟这一种方法。一个例子:

$sut = $this->getMock('Your\Class', array('onBeforeReset'));

方法的第二个参数getMock是数组,包含 phpunit 将模拟的方法。如果这个数组是空的,phpunit 将模拟对象中的所有方法,但是如果你精确到至少一个方法,phpunit 将只模拟你传入这个数组的 methodz。

你像往常一样模拟方法:

$sut->expects($this->any())
    ->method('onBeforeReset')
    ->will($this->returnValue(true));

最后你可以测试你想要测试的方法:

$this->assertWhatever($expectedValue, $sut->reset());
于 2013-06-04T11:32:08.590 回答
0

我如何理解单元测试,是你测试你的类的公共接口。因此,在您的示例中,您仅断言 reset() 的结果,而不是在内部调用的所有受保护和私有函数。然后,您从 reset() 给出的结果中推断出 onBeforeReset() 给出的结果。

这当然不是 100% 的规则。有时您真的想测试私有或受保护的方法,无论出于何种原因(但请考虑这可能意味着您实际上应该重构您的代码)。

PHPUnit 的创建者写了一些想法并给出了一些示例(http://sebastian-bergmann.de/archives/881-Testing-Your-Privates.html)。基本上,您使用反射使私有和受保护的方法和属性可公开访问。

于 2013-06-04T11:31:38.450 回答