【问题标题】:How do I mock the Doctrine PersistentCollection in PHPUnit如何在 PHPUnit 中模拟 Doctrine PersistentCollection
【发布时间】:2014-01-16 18:19:02
【问题描述】:

有人知道如何模拟 Doctrine PersistentCollection 吗?

当我尝试使用 PHPUnit 和 Mockery 直接模拟类时,我得到一个异常,内容如下:

Mockery\Exception: The class Doctrine\ORM\PersistentCollection is marked final a

它的方法不能被替换。标记为 final 的类可以传递给 \Moc kery::mock() 作为实例化对象来创建部分模拟,但前提是 m ock 不受类型提示检查。

我的研究表明,一旦方法被标记为 final,Mockery 和/或 phpUnit 就不能使用反射。

然后我尝试创建一个 stdClass 并为其提供迭代器将使用的方法(有效/当前/下一个),但除非该类实现迭代器,否则 foreach 循环不会调用这些方法。

因此,下面的代码不起作用...

$this -> collectionMock = \Mockery::mock('PersistentCollection, Traversable');
$this -> collectionMock -> shouldReceive('rewind');
$this -> collectionMock -> shouldReceive('valid') -> andReturn('true');
$this -> collectionMock -> shouldReceive('next');
$this -> collectionMock -> shouldReceive('current') ->andReturn();

并且 throws 似乎会抛出以下致命错误:

Fatal error: Cannot redeclare Mockery_1670979900_PersistentCollection_Traversable::rewind() 
in C:\zendProject\zf2\vendor\mockery\mockery\library\Mockery\Generator.php(129) :
eval()'d code on line 43

有没有人想出一个模拟这个类的好方法

【问题讨论】:

  • 我用一个可能的解决方案更新了我的答案。我自己使用了该解决方案并获得了很好的结果(尽管它与您的环境不同)。

标签: php unit-testing doctrine-orm phpunit


【解决方案1】:

我似乎无法模拟已声明为 final 的类。然而,可能会有一些希望。由于PersistentCollection 实现了Doctrine\Common\Collections\CollectionDoctrine\Common\Collections\Selectable,因此您可以使用Mockery 模拟实现这两个接口的对象。

Mockery::mock(
    'Doctrine\Common\Collections\Collection, Doctrine\Common\Collections\Selectable'
);

我在自己的一个项目中使用了used this to good effect

至于为什么你不能模拟最终课程,这是我能找到的最好的:

嘲讽

使用 Mockery 模拟最终类的能力是 limited

同样,主要目的是确保模拟对象继承特定类型以进行类型提示。有一个例外,标记为 final 的类或标记为 final 的方法不能被完全模拟。在这些情况下,必须使用部分模拟(稍后解释)。

$mock = \Mockery::mock('alias:MyNamespace\MyClass');

在链接页面中搜索“final”。你会找到我能找到的所有文档。

PHPUnit

尝试在 PHPUnit throws an exception by design 中模拟最终类。

【讨论】:

    猜你喜欢
    • 2019-08-07
    • 2013-10-10
    • 2015-02-12
    • 2012-09-23
    • 2017-06-29
    • 2018-10-10
    • 2020-09-28
    • 2011-10-06
    • 1970-01-01
    相关资源
    最近更新 更多