简体   繁体   中英

Mock view helper in Zend Framework 3 in PHPUnit test

I want to test a specific controller action in Zend Framework 3. Because I use ZfcUser ( https://github.com/ZF-Commons/ZfcUser ) and Bjyauthorize ( https://github.com/bjyoungblood/BjyAuthorize ) I need to mock some view helpers. For example I need to mock isAllowed view helper and let it return true always:

class MyTest extends AbstractControllerTestCase
{
    public function setUp()
    {
        $this->setApplicationConfig(include 'config/application.config.php');
        $bootstrap      = \Zend\Mvc\Application::init(include 'config/application.config.php');
        $serviceManager = $bootstrap->getServiceManager();

        $viewHelperManager = $serviceManager->get('ViewHelperManager');

        $mock = $this->getMockBuilder(IsAllowed::class)->disableOriginalConstructor()->getMock();
        $mock->expects($this->any())->method('__invoke')->willReturn(true);

        $viewHelperManager->setService('isAllowed', $mock);

        $this->getApplication()->getServiceManager()->setAllowOverride(true);
        $this->getApplication()->getServiceManager()->setService('ViewHelperManager', $viewHelperManager);
    }

    public function testViewAction()
    {
        $this->dispatch('/myuri');
        $resp = $this->getResponse();
        $this->assertResponseStatusCode(200);
        #$this->assertModuleName('MyModule');
        #$this->assertMatchedRouteName('mymodule/view');
    }
}

In my view.phtml (which will be rendered by opening/dispatching /myuri uri) I call the view helper $this->isAllowed('my-resource') .

But I got response code 500 with failing exception when executing testViewAction() :

Exceptions raised:
Exception 'Zend\ServiceManager\Exception\ServiceNotFoundException' with message 'A plugin by the name "isAllowed" was not found in the plugin manager Zend\View\HelperPluginManager' in ../vendor/zendframework/zend-servicemanager/src/AbstractPluginManager.php:131

How can I inject my isAllowed mock to the view helper manager in a way, that let the test case ( testViewAction / $this->dispatch() ) pass.

As stated in the previous answer already, we need to override the ViewHelper within the ViewHelperManager in the application object. The following code shows how this could be achieved:

public function setUp()
{
    $this->setApplicationConfig(include 'config/application.config.php');
    $bootstrap = \Zend\Mvc\Application::init(include 'config/application.config.php');
    $serviceManager = $bootstrap->getServiceManager();

    // mock isAllowed View Helper of Bjyauthorize
    $mock = $this->getMockBuilder(IsAllowed::class)->disableOriginalConstructor()->getMock();
    $mock->expects($this->any())->method('__invoke')->willReturn(true);

    // inject the mock into the ViewHelperManager of the application
    $this->getApplication()->getServiceManager()->get('ViewHelperManager')->setAllowOverride(true);
    $this->getApplication()->getServiceManager()->get('ViewHelperManager')->setService('isAllowed', $mock);
}

ViewHelperManager is an other instance of service manager. and it's not allowed to override source code . Can you try "setAllowOverride" before "setService" method?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM