Yii 和 PHPUnit 使用 fluent/mockbuilder 模拟会产生奇怪的结果

Posted

技术标签:

【中文标题】Yii 和 PHPUnit 使用 fluent/mockbuilder 模拟会产生奇怪的结果【英文标题】:Yii & PHPUnit mocking with fluent/mockbuilder gives weird results 【发布时间】:2013-08-07 22:06:17 【问题描述】:

为什么会这样:

 $mock = $this->getMock("EventDispatcher");
 $mock->expects($this->once())->method("fireEvent");

不一样:

$mock = $this->getMock("EventDispatcher")->expects($this->once())->method("fireEvent");

都试过了

Yii::app()->setComponent("dispatch",$mock);

第一个有效,最后一个给出致命错误:

致命错误:无法使用 phpUnit_Framework_MockObject_Builder_InvocationMocker 类型的对象作为 /var/www/frameworks/yii/base/CModule.php 第 438 行中的数组

我希望这两件事有相同的结果,还是我只是在完全崩溃的时候写了这段代码?

【问题讨论】:

【参考方案1】:
$mock = $this->getMock("EventDispatcher");

这个初始调用将返回实际的模拟对象。

$mock->expects($this->once())->method("fireEvent");

这一行利用 PHPUnit 提供的流畅接口来构建您想要的模拟行为。这里我们实际上并没有使用返回类型,因为它没有分配给任何变量,但是如果我们查看它,我们会发现它的类型是PHPUnit_Framework_MockObject_Builder_InvocationMocker。这将允许我们链接其他行为,例如

$mock->expects($this->once())
     ->method("fireEvent")
     ->with($this->equalTo('expectedParam'))
    ;

你的第二个例子:

$mock = $this->getMock("EventDispatcher")
                 ->expects($this->once())
                 ->method("fireEvent")
    ;

将以相同的方式创建模拟,但是由于方法链接在一行上,我们无法访问模拟本身。像这样链接方法调用时的行为是最终调用的返回值成为分配的值,但如图所示,这将是PHPUnit_Framework_MockObject_Builder_InvocationMocker。调用getMock() 会返回实际的模拟,但不会调用method()

【讨论】:

以上是关于Yii 和 PHPUnit 使用 fluent/mockbuilder 模拟会产生奇怪的结果的主要内容,如果未能解决你的问题,请参考以下文章

使用 Yii 进行 PHPUnit 敏捷 Web 开发

如何使用 phpunit 模拟 Yii@1.1 的 CActiveRecord(避免空属性)?

使用 yii 在 phpunit 中找不到类“CDbTestCase”错误

phpunit,在yii1中使用其他fixture

PHPUnit 测试中 Yii2 中的模拟视图助手

php 安装 yii 报错: phpunit/phpunit 4.8.32 requires ext-dom *