模拟 Demeter 链和流接口
这两个术语都指调用类似如下语句的日益普遍的做法:
这两个术语都指调用类似如下语句的日益普遍的做法:
$object->foo()->bar()->zebra()->alpha()->selfDestruct();
长链式方法调用不一定是坏事,前提是每个方法都返回调用类已知的本地对象。举个有趣的例子,Mockery 的长链(在第一个 shouldReceive() 方法之后)都调用同一个 \Mockery\Expectation 实例。然而,有时情况并非如此,链条不断跨越对象边界。
无论哪种情况,模拟这样的链都可能是一个非常困难的任务。为了简化操作,Mockery 支持 Demeter 链式模拟。基本上,我们可以通过链条快捷方式,直接从最终调用返回一个定义好的值。例如,假设 selfDestruct() 返回字符串 "Ten!" 给 $object(一个 CaptainsConsole 实例)。我们可以这样模拟它:
$mock = \Mockery::mock('CaptainsConsole');
$mock->shouldReceive('foo->bar->zebra->alpha->selfDestruct')->andReturn('Ten!');
上述期望可以遵循任何之前见过的格式或期望,只是方法名是由所有预期链调用用 -> 分隔的字符串。Mockery 会自动设置预期调用链及其最终返回值,而不管真实实现中使用了什么中间对象。
在此过程中,链中所有成员的参数(除了最终调用)都会被忽略。