PHPUnit和Abstract类:如何测试接受参数和其他具体方法的具体构造函数

Aer*_*dir 5 php phpunit abstract-class unit-testing

我有一个非常简单的类,如下所示:

abstract class Person
{
    private $id;
    private $createdOn;

    // ... More private properties

    protected $unfound = array();
Run Code Online (Sandbox Code Playgroud)

构造函数对传递的数组$ data执行操作,并使用正确的方法将值分配给属性.如果该方法不存在,那么将密钥添加到受保护的数组中以保留它的跟踪(我称之为$ unfound,只是为了原始!).

    public function __construct($data)
    {
        foreach ($data as $field => $value)
        {
            $method = 'set' . ucfirst($field);

            if (method_exists($this, $method))
            {
                $this->$method($value);
            }
            else
            {
                $this->unfound[] = $field;
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

设置属性值的方法列表

    public function setId($id) {
        $this->id = $id;
    }

    public function setCreatedOn($createdOn) {
        $this->createdOn = $createdOn;
    }
Run Code Online (Sandbox Code Playgroud)

以及获取这些指定值的方法列表

    public function getId() {
        return $this->id;
    }

    public function getCreatedOn() {
        return $this->createdOn;
    }
} // END of the class
Run Code Online (Sandbox Code Playgroud)

如您所见,该类不执行任何复杂的任务:它接受类似的数组

array(
    'id' => 4,
    'createdOn' => '2015-01-07 20:50:00',
    'unknownVar' => 'mah'
    // ... Other properties to set
    );
Run Code Online (Sandbox Code Playgroud)

因此,类循环遍历数组并使用键调用正确的方法来设置值.我觉得没什么复杂的.

相反,更复杂的是测试它.

因为它是一个抽象类,我不能直接实例化它,但我必须嘲笑它​​.

我的问题是,我无法传递给构造函数正确的参数来测试值分配是否正确完成.

我试过用类似的东西:

public function testPerson()
{
   $abstractClass = '\My\Namespace\Person';

    $testData = array(
        'id' => 1,
        'createdOn' => '2015-01-07 19:52:00',
        'unfound' => 'Inexistent method'
        );

   $methods = array(
      'getId',
      'setId'
      );

    $mock = $this->getMockBuilder($abstractClass)
        ->setConstructorArgs(array($testData))
        ->setMethods($methods)
        ->getMockForAbstractClass();

    $this->assertEquals($testData['id'], $mock->getId());
}
Run Code Online (Sandbox Code Playgroud)

在testPerson()中,$ methods变量不包含我需要的所有方法,但是对于测试的测试(请原谅我玩文字!:))我认为它们已经足够了.

但PHPUnit告诉我:

Failed asserting that null matches expected 1.
Run Code Online (Sandbox Code Playgroud)

似乎构造函数没有被调用,如果代码覆盖率告诉我方法被调用.

是否有人可以帮助我了解正在发生的事情以及如何测试这门课程?

谢谢!

Aer*_*dir 3

解决办法很简单:删除$methods变量并调用即可setMethods($methods)解决问题!

事实上,调用setMethods()“存根”那些在没有设置适当的固定值的情况下设置为 null(我从测试结果中收到的值)的方法。

我测试的方法被破坏了,而其他方法则没有。

因此 aprint_r($mock)表明其他值设置正确。

如此简单但很难找到!不管怎样,谢谢你让我思考,所以我解决了问题并提出了问题!