PHPUnit固定受保护方法返回的值的最佳实践?

时间:2011-09-26 12:24:38

标签: php phpunit

将以下代码视为PHP样式的伪代码,以便了解我的观点。

class C extends PHPUnit_Framework_TestCase
{
  public function m1()
  {
    $v = $this->m2();

    if($v == "x")
    {
      throw new Exception();
    }
  }

  protected function m2()
  {
    [...];

    return $v;
  }
}

现在我想添加一个测试,如果m2()返回“x”,则断言抛出异常。

我该如何模拟?

我考虑过在运行时使用Reflection重新定义方法,但似乎Reflection没有提供这样的功能,我不得不求助于像classkit或runkit这样的实验性扩展。这会是要走的路吗?

在这种情况下,我可以扩展类并重新定义m2(),但是我会在哪里放置该派生类?在与测试相同的文件中?

如果我选择m2为私有,后一种解决方案将不再适用。

我很确定最好的做法是处理这种情况。

2 个答案:

答案 0 :(得分:4)

以太我完全不关心你在这里做什么,或者你做的事情让我很困惑。

对我而言,似乎您要求检查您的测试方法是否会引发异常

  

C类扩展了PHPUnit_Framework_TestCase

为什么要测试您的测试方法?


我将假设这是真正的课程,而不是你的考试

在这种情况下,我总是强烈要求对其进行测试,好像受保护的方法将在公共方法中内联。

您想测试班级的外部行为。不是实施。受保护的方法是 test 不应该关心的实现细节。这意味着当您更改受保护的方法时,您必须更改测试。

从此开始:

class CTest extends PHPUnit_Framework_TestCase {

     public function testM1NormalBehavior() {

     }

     /**
      * @expectedException YourException
      */
     public function testM1ThrowsExceptionWhenM2ConditionsAreMet() {
         $c = new C('set_Up_In_A_Way_That_Makes_M2_Return_X');
         $c->m1();
     }

}

答案 1 :(得分:3)

您可以使用C的部分模拟来强制m2()返回"x"。我假设extends PHPUnit_Framework_TestCase是偶然的,C实际上是被测试的类,而不是单元测试本身。

class CTest extends PHPUnit_Framework_TestCase {
    /**
     * @expectedException Exception
     */
    function testM1ThrowsExceptionWhenM2ReturnsX() {
        $c = $this->getMock('C', array('m2'));
        $c->expects($this->once())->method('m2')->will($this->returnValue('x'));
        $c->m1();
    }
}