如何使用PHPUnit测试深度克隆

如何使用PHPUnit测试深度克隆,php,phpunit,clone,deep-copy,Php,Phpunit,Clone,Deep Copy,我已经在类上实现了\u clone,以克隆子对象(即深度克隆) 我想编写测试来确保这个过程得到正确实现 当我模拟a子对象并尝试设置对“\uu clone”的期望时,PHPUnit会出错,因为该方法未定义。这是我如何尝试编写断言的一个示例 <?php public function testClone() { $mockChildObject = $this->createMock(ChildObject::class); $mockChildObjectClone

我已经在类上实现了
\u clone
,以克隆子对象(即深度克隆)

我想编写测试来确保这个过程得到正确实现

当我模拟a子对象并尝试设置对“\uu 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());
}

我注意到,在
MockBuilder
上调用
disableOriginalClone
方法将等同于以下代码(如果
\u clone
方法不在禁止的模拟方法列表中,并且没有产生警告):


这就是为什么对于模拟克隆方法,你可以简单地使用
disableOriginalClone
方法。

对于第三方来说很晚,但你可以使用
assertNotSame

<?php

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

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

能否从克隆中调用模板方法,并模拟该方法?因此,例如在您的
\u克隆中,调用
return$this->myActualCloneMethod()
并模拟
myActualCloneMethod
方法。在没有测试的情况下,我假设它总是被调用。
<?php

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

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