测试抽象类

如何使用 PHPUnit 测试抽象类的具体方法?

我希望我必须创建某种类型的对象作为测试的一部分。不过,我不知道这方面的最佳实践是什么,也不知道 PHPUnit 是否允许这样做。

60995 次浏览

Eran,您的方法应该可以工作,但是它违背了在实际代码之前编写测试的趋势。

我建议您针对所讨论的抽象类的非抽象子类的所需功能编写测试,然后同时编写抽象类和实现子类,最后运行测试。

您的测试显然应该测试抽象类的已定义方法,但总是通过子类。

如果您不想仅仅为了对已经在抽象类中实现的方法执行单元测试而对抽象类进行子类化,那么您可以尝试查看您的框架是否允许您使用 嘲笑抽象类。

尼尔森的回答是错误的。

抽象类并不要求它们的所有方法都是抽象的。

实现的方法是我们需要测试的方法。

您可以做的是在单元测试文件上创建一个假的存根类,让它扩展抽象类,只实现需要的东西,当然,不需要任何功能,然后测试它。

干杯。

抽象类的单元测试并不一定意味着测试接口,因为抽象类可以有具体的方法,而这些具体的方法可以测试。

在编写某些库代码时,在应用程序层中具有某些希望扩展的基类并不罕见。如果你想确保库代码被测试,你需要一些方法来 UT 抽象类的具体方法。

就我个人而言,我使用 PHPUnit,它有所谓的存根和模拟对象来帮助您测试这类东西。

来自 PHPUnit 手册:

abstract class AbstractClass
{
public function concreteMethod()
{
return $this->abstractMethod();
}


public abstract function abstractMethod();
}


class AbstractClassTest extends PHPUnit_Framework_TestCase
{
public function testConcreteMethod()
{
$stub = $this->getMockForAbstractClass('AbstractClass');
$stub->expects($this->any())
->method('abstractMethod')
->will($this->returnValue(TRUE));


$this->assertTrue($stub->concreteMethod());
}
}

模拟对象给你几样东西:

  • 您不需要具体实现抽象类,可以使用存根代替
  • 您可以调用具体的方法并断言它们正确执行
  • 如果具体方法依赖于未实现(抽象)方法,则可以使用 will () PHPUnit 方法存根返回值

问得好,我也在找这个。
幸运的是,PHPUnit 已经为这种情况提供了 getMockForAbstractClass()方法,例如。

protected function setUp()
{
$stub = $this->getMockForAbstractClass('Some_Abstract_Class');
$this->_object = $stub;
}

重要提示:

注意,这需要 PHPUnit > 3.5.4。

升级到最新版本:

sudo pear channel-update pear.phpunit.de
sudo pear upgrade phpunit/PHPUnit

值得注意的是,从 PHP7开始,已经添加了对 匿名类的支持。这为设置抽象类的测试提供了一个额外的途径,该测试不依赖于特定于 PHPUnit 的功能。

class AbstractClassTest extends \PHPUnit_Framework_TestCase
{
/**
* @var AbstractClass
*/
private $testedClass;


public function setUp()
{
$this->testedClass = new class extends AbstractClass {


protected function abstractMethod()
{
// Put a barebones implementation here
}
};
}


// Put your tests here
}