2017 © Pedro Peláez
 

library actioninjections

ZF2 Module wich allows to inject dependencies in controller action

image

t4web/actioninjections

ZF2 Module wich allows to inject dependencies in controller action

  • Saturday, October 24, 2015
  • by maxgu
  • Repository
  • 2 Watchers
  • 0 Stars
  • 90 Installations
  • PHP
  • 1 Dependents
  • 0 Suggesters
  • 1 Forks
  • 0 Open issues
  • 3 Versions
  • 6 % Grown

The README.md

ActionInjections

Master: Build Status codecov.io Scrutinizer Code Quality SensioLabsInsight Dependency Status, (*1)

Introduction

ZF2 Module wich allows to inject dependencies in controller action for better incapsulate testing and remove controller dependency from ServiceLocator., (*2)

Problem: I have simply CRUD Controller, with actions "create", "update", "show", "delete", i have 3 dependency in action "delete": ViewModel, Request, some Service., (*3)

class AjaxController extends Zend\Mvc\Controller\AbstractActionController
{
    public function deleteTimesheetAction() {
        $view = new ViewModel();

        if (!$this->getRequest()->isPost()) {
            return $view;
        }

        $timesheetDeleteService = $this->getServiceLocator()->get('Timesheet\Timesheet\Service\Delete');

        $timesheetId = $this->getRequest()->getPost()->get('id', 0);
        if (!$timesheetDeleteService->delete($timesheetId)) {
            $view->errors = $timesheetDeleteService->getErrors();
        }

        return $view;
    }
    //...
}

in this case i can't easy test this controller, because: 1. I can't mock ViewModel (constructor calling) 2. Very difficult create test for this $this->getRequest()->getPost()->get('id', 0); 3. Nobody understand dependencies in current controller, because $this->getServiceLocator()->get('SomeService') inside controller - is bad practice, (*4)

Ok, refactor it.., (*5)

Problem: I have simply CRUD Controller, with actions "create", "update", "show", "delete", i have 3 dependency in action "delete": ViewModel, Request, some Service. For height testability i add all dependencies in Controller::__constructor()., (*6)

class AjaxController extends Zend\Mvc\Controller\AbstractActionController
{
    /**
     * @var BaseFinder
     */
    private $timesheetFinder;

    /**
     * @var BaseFinder
     */
    private $calendarFinder;

    /**
     * @var CreateInterface
     */
    private $createService;

    /**
     * @var UpdateInterface
     */
    private $updateService;

    /**
     * @var DeleteInterface
     */
    private $deleteService;

    /**
     * @var AjaxViewModel
     */
    private $view;

    public function __construct(
        BaseFinder $timesheetFinder,
        BaseFinder $calendarFinder,
        CreateInterface $timesheetCreateService,
        UpdateInterface $timesheetUpdateService,
        DeleteInterface $timesheetDeleteService,
        AjaxViewModel $view)
    {

        $this->timesheetFinder = $timesheetFinder;
        $this->calendarFinder = $calendarFinder;
        $this->createService = $timesheetCreateService;
        $this->updateService = $timesheetUpdateService;
        $this->deleteService = $timesheetDeleteService;
        $this->view = $view;
    }

    public function deleteTimesheetAction() {
        $view = new ViewModel();

        if (!$this->getRequest()->isPost()) {
            return $this->view;
        }

        $timesheetId = $this->getRequest()->getPost()->get('id', 0);
        if (!$this->deleteService->delete($timesheetId)) {
            $this->view->errors = $this->deleteService->getErrors();
        }

        return $this->view;
    }
    // ...
}
class AjaxControllerFactory implements FactoryInterface {

    public function createService(ServiceLocatorInterface $serviceLocator) {
        $serviceManager = $serviceLocator->getServiceLocator();
        return new AjaxController(
            $serviceManager->get('Timesheet\Timesheet\Service\Finder'),
            $serviceManager->get('Calendar\Calendar\Service\Finder'),
            $serviceManager->get('Timesheet\Timesheet\Service\Create'),
            $serviceManager->get('Timesheet\Timesheet\Service\Update'),
            $serviceManager->get('Timesheet\Timesheet\Service\Delete'),
            $serviceManager->get('Timesheet\Controller\ViewModel\AjaxViewModel')
        );
    }
}

in this case i can easy test this controller, but: 1. I have to big __constructor (almost god object) 2. How many mock's i must create for test on method "delete"? 3. Nobody understand where i use each dependency in current controller 4. I must test ControllerFactory, (*7)

Solution: use t4web/ActionInjections Add in your module.config.php section controller_action_injections, (*8)

    'controller_action_injections' => array(
        'Timesheet\Controller\User\AjaxController' => array(
            'deleteTimesheetAction' => array(
                'request',
                'Timesheet\Controller\ViewModel\AjaxViewModel',
                'Timesheet\Timesheet\Service\Delete',
            ),
        ),
    ),

where request, Timesheet\Controller\ViewModel\AjaxViewModel, Timesheet\Timesheet\Service\Delete your dependecies, and just use it in your controller action, (*9)

class AjaxController extends Zend\Mvc\Controller\AbstractActionController
{
    public function deleteTimesheetAction(HttpRequest $request, AjaxViewModel $view, DeleteInterface $timesheetDeleteService) {
        if (!$request->isPost()) {
            return $view;
        }

        $timesheetId = $request->getPost()->get('id', 0);
        if (!$timesheetDeleteService->delete($timesheetId)) {
            $view->setErrors($timesheetDeleteService->getErrors());
        }

        return $view;
    }
    //...
}

and test it:, (*10)

class AjaxControllerTest extends \PHPUnit_Framework_TestCase {

    public function testDeleteTimesheetAction_Delete_ReturnView() {
        $requestMock = $this->getMockBuilder('Zend\Http\PhpEnvironment\Request')->disableOriginalConstructor()->getMock();
        $timesheetDeleteServiceMock = $this->getMockBuilder('T4webBase\Domain\Service\Delete')->disableOriginalConstructor()->getMock();
        $ajaxViewModel = new AjaxViewModel();

        $timesheetId = 1;
        $parameters = new Parameters(array('id' => $timesheetId));

        $requestMock->expects($this->once())
            ->method('isPost')
            ->will($this->returnValue(true));

        $requestMock->expects($this->once())
            ->method('getPost')
            ->will($this->returnValue($parameters));

        $timesheetDeleteServiceMock->expects($this->once())
            ->method('delete')
            ->with($this->equalTo($timesheetId))
            ->will($this->returnValue(true));

        $controller = new AjaxController();

        /** @var $result AjaxViewModel */
        $result = $controller->deleteTimesheetAction($requestMock, $ajaxViewModel, $timesheetDeleteServiceMock);

        $this->assertEquals($ajaxViewModel, $result);
    }
    //...
}

very fast, easy, readable, incapsulate unit test., (*11)

Requirements

Installation

Main Setup

By cloning project

Clone this project into your ./vendor/ directory., (*12)

With composer

Add this project in your composer.json:, (*13)

"repositories": [
        {
            "type": "git",
            "url": "https://github.com/t4web/actioninjections.git"
        }
],

"require": {
    "t4web/actioninjections": "dev-master"
}

Now tell composer to download Authentication by running the command:, (*14)

$ php composer.phar update

Post installation

Not need enabling it in your application.config.phpfile, just extends from T4webActionInjections\Mvc\Controller\AbstractActionController, (*15)

Testing

Unit test runnig from authentication module directory., (*16)

$ phpunit

The Versions

24/10 2015

dev-master

9999999-dev https://github.com/robaks/ActionInjections

ZF2 Module wich allows to inject dependencies in controller action

  Sources   Download

BSD-3-Clause

The Requires

 

The Development Requires

by Avatar ross

zf2 action injections injections

24/10 2015

1.0.1

1.0.1.0 https://github.com/robaks/ActionInjections

ZF2 Module wich allows to inject dependencies in controller action

  Sources   Download

BSD-3-Clause

The Requires

 

The Development Requires

by Avatar ross

zf2 action injections injections

14/09 2015

1.0.0

1.0.0.0 https://github.com/robaks/ActionInjections

ZF2 Module wich allows to inject dependencies in controller action

  Sources   Download

BSD-3-Clause

The Requires

 

The Development Requires

by Avatar ross

zf2 action injections injections