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
来做,但这会使原来的功能变得不可行。
答案 0 :(得分:1)
不要模仿私有方法。甚至不要尝试测试它们。它们是您不需要关注的课程细节。你关心的只是公共职能所做的事情。在你的例子中哪一个什么都没有(它调用两个返回值并且不对它们做任何事情的方法)。
但是假设该方法减去了两个值。所以函数看起来像这样:
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()
中的额外功能被移动到新的私有函数中,则测试将通过。
指定调用私有函数会降低您的测试可用性并使重构代码变得更加困难。重构不应该改变功能,因此不应导致测试失败。指定私有方法意味着您必须确定由于删除了私有方法而导致测试失败,或者您是否引入了错误。
如果您的私人功能极其复杂,您觉得需要单独进行测试。这是一种代码气味,也许这些方法应该被提取到他们自己的类中。