Mock view helper in Zend Framework 3 in PHPUnit test

1k views Asked by At

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.

2

There are 2 answers

0
koseduhemak On BEST ANSWER

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);
}
0
Mehmet SÖĞÜNMEZ On

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