如何使用PHPUnit测试深度克隆

时间:2017-01-16 04:36:17

标签: php phpunit clone deep-copy

我在类上实现了__clone来克隆子对象(即深度克隆)。

我想编写测试以确保正确实现此过程。

当我模拟子对象并尝试对' __ clone',PHPUnit错误设置期望时,因为该方法未定义。这是我尝试编写断言的一个例子。

<?php

public function testClone()
{
    $mockChildObject = $this->createMock(ChildObject::class);
    $mockChildObjectClone = $this->createMock(ChildObject::class);
    $mockChildObject->expects($this->once())->method('__clone')->willReturn($this->createMock($mockChildObjectClone));

    $object = new MyObject();
    $object->addChild($mockChildObject);

    $objectClone = clone $object;

    $this->assertSame($mockChildObjectClone, $objectClone->getChild());
}

结果错误显示为:

  

尝试配置方法&#34; __ clone&#34;无法配置,因为它不存在,尚未指定,是最终的,还是静态的

未在子对象上实现__clone方法,因为默认克隆就足够了。

我还尝试将$this->getMockBuilder()disableOriginalClone() / enableOriginalClone()enableArgumentCloning() / diableArgumentCloning()的各种组合结合使用。

我能想到测试克隆的唯一方法是编写另一个扩展子对象并实现__clone()的类。但这似乎过分,我确信必须有一个更实际的解决方案。

1 个答案:

答案 0 :(得分:0)

聚会迟到,但您可以利用assertNotSame

<?php

public function testClone()
{
    $sut = new MyObject();
    $sut->addChild(
        $originalMock = $this->createMock(ChildObject::class)
    );
    
    $sutClone = clone $sut;

    $this->assertNotSame($originalMock, $sutClone->getChild());
}

根据PHPUnit documentationassertSame

<块引用>

如果两个变量 $expected 和 $actual 没有引用同一个对象,则报告由 $message 标识的错误。

这正是您需要测试的:克隆 SUT 的孩子不是原始孩子。