如何让Mockery使用demeter链

时间:2014-02-20 14:35:41

标签: php mockery

我有一个Slim应用程序,它有一些中间件。

它对路由执行身份验证,并像这样检索路由:

$route = $this->getApplication()->router()->getCurrentRoute();

我现在正在测试它并尝试使用Mockery来模拟链接调用的结果,因此我可以有效地指定路由。

$mock = M::mock('\Api\SessionMiddleware[getApplication]');
$mock->shouldReceive('router->getCurrentRoute')->andReturn('myRoute');

这不起作用。它试图调用:require('lib/demeter/router.php')并失败,因为它不存在。

我也试过了:

$mock = M::mock('\Api\SessionMiddleware')->shouldDeferMissing();
$mock->shouldReceive('getApplication->router->getCurrentRoute')->andReturn('myRoute');

这也不起作用,但没有:

Failed opening required 'lib/demeter/getApplication.php'

我错过了什么?

2 个答案:

答案 0 :(得分:3)

即使有一个公认的答案,我也想为未来的用户提供另一种解决方案。

如果路由器仅用作demeter链的中间步骤,则无需模拟路由器。试试这个:

$mock = M::mock('\Api\SessionMiddleware');
$mock->shouldReceive('getApplication->router->getCurrentRoute')->andReturn('myRoute');

关键是删除对shouldDeferMissing()的调用,在这种情况下似乎会干扰demeter链。

这样,返回一个“纯”模拟,它不会将任何内容转发给SessionMiddleware的实际实现。在调用'myRoute'时,它应该可以使用$mock->getApplication()->getRouter()->getCurrentRoute()回复。

答案 1 :(得分:1)

您还需要模拟路由器。然后让router()方法依次返回路由器模拟。

$mock = M::mock('\Api\SessionMiddleware[getApplication]');
$routerMock = M::mock('My\Router');
$routerMock->shouldReceive('getCurrentRoute')->andReturn('myRoute');
$mock->shouldReceive('router')->andReturn($routerMock);