【问题标题】:How to mock Carbon method chain如何模拟 Carbon 方法链
【发布时间】:2014-06-07 05:49:40
【问题描述】:
我正在尝试模拟 Carbon::parse($date)->format("Y"),但我不知道该怎么做。
这是我目前所拥有的:
public function testGetYear2014FromPost()
{
$mock = Mockery::mock("DateFormatter");
$mock->shouldReceive("parse")
->with("2014-02-08 16:23:33")
->once()
->andReturn($mock);
$mock->shouldReceive("format")
->with("Y")
->once()
->andReturn("2014");
$this->article->setDateFormatter($mock);
$this->assertEquals("2014", $this->article->getYear());
}
【问题讨论】:
标签:
laravel-4
tdd
mockery
php-carbon
【解决方案1】:
我知道只有两种方法可以像这样模拟方法链:
- 找出每个方法的返回值并模拟:
$mock1 = Mockery::mock("SomeOtherClass")
$mock1->shouldReceive("format")->with("Y")->once()->andReturn("2014");
$mock0 = Mockery::mock("DateFormatter")
$mock0->shouldReceive("parse")
->with("2014-02-08 16:23:33")->once()->andReturn($mock1);
您必须弄清楚 parse 方法返回什么类,然后将其设置为模拟对象并返回它。
- 如果您不想费心找出返回的类是什么,您可以使用
stdClass 对象来伪造它:
$mock1 = new stdClass;
$mock1->format = function ($f) { return "2014"; };
$mock0 = Mockery::mock("DateFormatter")
$mock0->shouldReceive("parse")
->with("2014-02-08 16:23:33")->once()->andReturn($mock1);
这两种方法之间有一个重要的区别:
$mock1 = 新标准类;
$mock1->格式=函数($f){
如果 ($f!="Y") {
抛出新异常;
}
返回“2014”;
};
$mock0 = 嘲弄::mock("DateFormatter")
$mock0->shouldReceive("解析")
->with("2014-02-08 16:23:33")->once()->andReturn($mock1);
然后你可以在你的方法中添加一个@expectedException Exception docblock 来测试它。