如何在ZF2单元测试中模拟invokable?

时间:2013-11-22 20:00:18

标签: unit-testing zend-framework2 phpunit

我正在尝试在具有使用视图助手的视图的控制器上运行单元测试。我的helokable设置在我的helper配置中,如下所示:

<?php
return [
    'invokables' => [
        'viewHelper' => 'Theme\View\Helper\ViewHelper',
    ],
];

在我的单元测试中,我在setUp()中模拟了许多服务。

<?php

namespace Blargle\Controller;

class ActivityControllerTest extends AbstractZendHttpControllerTestCase
{
    /**
     * Someone set up us the bomb.
     */
    public function setUp()
    {
        parent::setUp();

        $mockActivityRepository = $this->getMock('Domain\Repository\Blargle\ActivityRepositoryInterface');
        $this->serviceManager->setService('Blargle\ActivityRepository', $mockActivityRepository);
    }

    /**
     * Test Add Action
     */
    public function testAddAction()
    {
        $this->createIdentity(); //Sets up the logged in user.

        $this->dispatch('/blargle/activity/add/1');
        $this->assertResponseStatusCode(200);

        $this->assertModuleName('blargle');
        $this->assertControllerName('Blargle\Controller\Activity');
        $this->assertControllerClass('ActivityController');
        $this->assertMatchedRouteName('blargle/activity');

        $mvcEvent = $this->getApplication()->getMvcEvent();
        $viewModel = $mvcEvent->getResult();

        $this->assertInstanceOf('Zend\View\Model\ViewModel', $viewModel);
        $this->assertEquals($viewModel->getTemplate(), 'blargle/activity/add');
    }
}

因此,我现在需要模拟视图加载的invokable,但视图所依赖的服务管理器与视图相关联。我试过了:

$mockHelper = $this->getMock('Theme\View\Helper\ViewHelper');
$this->serviceManager->setService('viewHelper', $mockHelper);

这是徒劳的,因为它现在存在于控制器服务管理器中,而同类产品似乎与视图一起产生。遗憾的是,该视图在服务出局之前会创建一个新的服务实例,并查看其对等实例。

那么,关于如何有效地模仿这个的任何想法?

1 个答案:

答案 0 :(得分:0)

请务必在发送请求之前模拟助手:)

public function testMethod()
{
    /**
      * mock of your invokable class
      */
    $mock = ...;

    $sm = $this->getApplicationServiceLocator();
    $sm->setAllowOverride(true);
    $sm->setService('viewHelper', $mock);
    $sm->setAllowOverride(false);

    // your invokable is now mocked
}