如何在PHPunit中测试抽象类?

8
假设我有一个文件在 /var/www/project/calculator.class.php
这是类的内容:
namespace App/Module/Calculator; 

abstract class calculator{

 static property $add; 

 static property $result; 

 function add($val_a, $val_b){
    return $a + $b; 
 }

}

我想为上面的类创建一个测试用例,但似乎无法测试。我卡在非常基础的阶段。

require '/var/www/project/calculator.class.php';

 class CalculatorTest extends \PHPUnit_Framework_TestCase {

    public function testAbstactDatabaseClassExists()
    {

       $this->assertEquals(is_object('Database'), 1);
      $this->assertEquals(true, in_array('Calculator', get_declared_classes()));

    }

 }

无论我做什么,似乎都没有办法测试这个类及其内容。 有人有任何想法吗?

你的类在语法上有错误。没有属性关键字,而且你的add方法必须使用$this(用于实例变量)或self::或static::(用于类变量)。 - GordonM
不要测试抽象类,测试具体类...如果必要的话,为你的抽象类创建一个小存根扩展类,以便你可以实例化它进行测试。 - Mark Baker
@MarkBaker 在许多情况下这是一个好建议,但如果有很多具体类扩展某个抽象基类,最好编写抽象类的测试并在其测试中测试具体类的专业功能。否则,您将最终拥有大量重复的测试。 - Strayobject
你只需要测试抽象方法一次,不需要为其他扩展它的具体类测试那些方法。 - Mark Baker
@MarkBaker 我从未听说过 PHP 中的具体类。我猜你是在指 stepozer 的答案?只需创建一个扩展类,然后以这种方式访问即可? - spartak
@spartak - 具体类是一个通用术语,指的是可以实例化的类,也就是说,不是抽象类 - http://en.wikipedia.org/wiki/Class_(computer_programming)#Abstract_and_concrete 或者 http://www.cems.uwe.ac.uk/~jsa/UMLJavaShortCourse09/CGOutput/Unit9/unit9(0809)/page_03.htm - Mark Baker
3个回答

14

在测试抽象类时,您可以使用PHPUnit的Mock功能。例如,对于add方法,代码如下:

public function testAdd() {
    /* @var $calculator \App\Module\Calculator\calculator|\PHPUnit_Framework_MockObject_MockObject */
    $calculator = $this
        ->getMockBuilder('App\Module\Calculator\calculator')
        ->getMockForAbstractClass();

    $result = $calculator->add(13, 29);
    $this->assertEquals(42, $result);
}

如需关于模拟的进一步信息,请参考PHPUnit手册


如果抽象类有一个需要参数的构造函数怎么办? - Miguel Stevens

0

您可以使用PHP匿名类。它们在5.3中被引入。如果您的抽象类有很多抽象方法,则可能不适用。

protected function createConcrete(...$args): YourAbstractClass
{
    return new class(...$args) extends YourAbstractClass {
        public function concreteImplementation(): void
        {

        }
    };
}

0

简单的方法 - 从计算器创建子类,并在测试中使用子类(但这不是好的实践):

class CalculatorChildForTest extends calculator
{
}
// your test here use CalculatorChildForTest
class CalculatorTest extends \PHPUnit_Framework_TestCase {

4
一个类文件里面包含两个类。不是我的菜。 - user3790897

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接