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 模拟会产生奇怪的结果的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 phpunit 模拟 Yii@1.1 的 CActiveRecord(避免空属性)?