Simple ZF2 Unit Tests for a controller using ZfcUser

后端 未结 2 1469
旧时难觅i
旧时难觅i 2020-12-16 04:09

I\'m having issues trying to unit test an action which uses ZfcUser for authentication. I need some way to mock the ZfcUser Controller plugin but I\'m not so sure how to do

相关标签:
2条回答
  • 2020-12-16 04:19

    The ZfcUser documentation suggests that this is a plugin so you need to inject this into the controller.

    You will need to amend your class names to pick up the ZfcUser classes

    Your mocks will also need to be addapted as getIdenty returns a different object.

    The following worked for me - insert in your phpunit setUp() method.

    $serviceManager = Bootstrap::getServiceManager();
    $this->controller = new RegisterController();
    $this->request    = new Request();
    $this->routeMatch = new RouteMatch(array('controller' => 'add'));
    $this->event      = new MvcEvent();
    $config = $serviceManager->get('Config');
    $routerConfig = isset($config['router']) ? $config['router'] : array();
    $router = HttpRouter::factory($routerConfig);
    $this->event->setRouter($router);
    $this->event->setRouteMatch($this->routeMatch);
    $this->controller->setEvent($this->event);
    $this->controller->setServiceLocator($serviceManager);
    $mockAuth = $this->getMock('ZfcUser\Entity\UserInterface');
    
    $ZfcUserMock = $this->getMock('ZfcUser\Entity\User');  
    
    $ZfcUserMock->expects($this->any())
                ->method('getId')
                ->will($this->returnValue('1'));
    
    $authMock = $this->getMock('ZfcUser\Controller\Plugin\ZfcUserAuthentication');
    
    $authMock->expects($this->any())
             ->method('hasIdentity')
                -> will($this->returnValue(true));  
    
    $authMock->expects($this->any())
             ->method('getIdentity')
             ->will($this->returnValue($ZfcUserMock));
    
    $this->controller->getPluginManager()
         ->setService('zfcUserAuthentication', $authMock);
    

    There may be an easier way would welcome other thoughts.

    0 讨论(0)
  • 2020-12-16 04:42

    This is how I did it.

    <?php
    
    namespace IssueTest\Controller;
    
    use Zend\Test\PHPUnit\Controller\AbstractHttpControllerTestCase;
    
    class IssueControllerTest extends AbstractHttpControllerTestCase
    {
        protected $serviceManager;
    
        public function setUp()
        {
            $this->setApplicationConfig(
                include '/media/policybubble/config/application.config.php'
            );
            parent::setUp();
            $ZfcUserMock = $this->getMock('ZfcUser\Entity\User');
            $ZfcUserMock->expects($this->any())
                ->method('getId')
                ->will($this->returnValue('1'));
            $authMock = $this->getMock(
                'ZfcUser\Controller\Plugin\ZfcUserAuthentication'
            );
            $authMock->expects($this->any())
                ->method('hasIdentity')
                ->will($this->returnValue(true));
            $authMock->expects($this->any())
                ->method('getIdentity')
                ->will($this->returnValue($ZfcUserMock));
            $this->serviceManager = $this->getApplicationServiceLocator();
            $this->serviceManager->setAllowOverride(true);
            $this->serviceManager->get('ControllerPluginManager')->setService(
                'zfcUserAuthentication', $authMock
            );
        }
    
        public function testIndexActionCanBeAccessed()
        {
            $this->dispatch('/issue');
            $this->assertResponseStatusCode(200);
            $this->assertModuleName('Issue');
            $this->assertControllerName('Issue\Controller\Issue');
            $this->assertControllerClass('IssueController');
            $this->assertMatchedRouteName('issue');
        }
    
        public function testAddActionRedirectsAfterValidPost()
        {
            $issueTableMock = $this->getMockBuilder('Issue\Model\IssueTable')
                ->disableOriginalConstructor()
                ->getMock();
            $issueTableMock->expects($this->once())
                ->method('saveIssue')
                ->will($this->returnValue(null));
            $this->serviceManager->setService('Issue\Model\IssueTable', $issueTableMock);
            $postData = array(
                'title' => 'Gun Control',
                'id'    => '',
            );
            $this->dispatch('/issue/add', 'POST', $postData);
            $this->assertResponseStatusCode(302);
            $this->assertRedirectTo('/issue');
        }
    
        public function testEditActionRedirectsAfterValidPost()
        {
            $issueTableMock = $this->getMockBuilder('Issue\Model\IssueTable')
                ->disableOriginalConstructor()
                ->getMock();
            $issueTableMock->expects($this->once())
                ->method('saveIssue')
                ->will($this->returnValue(null));
            $this->serviceManager->setService('Issue\Model\IssueTable', $issueTableMock);
            $issueTableMock->expects($this->once())
                ->method('getIssue')
                ->will($this->returnValue(new \Issue\Model\Issue()));
            $postData = array(
                'title' => 'Gun Control',
                'id'    => '1',
            );
            $this->dispatch('/issue/edit/1', 'POST', $postData);
            $this->assertResponseStatusCode(302);
            $this->assertRedirectTo('/issue');
        }
    
        public function testDeleteActionRedirectsAfterValidPost()
        {
            $postData = array(
                'title' => 'Gun Control',
                'id'    => '1',
            );
            $this->dispatch('/issue/delete/1', 'POST', $postData);
            $this->assertResponseStatusCode(302);
            $this->assertRedirectTo('/issue');
        }
    }
    
    <?php
    
    namespace Issue\Controller;
    
    use Zend\Mvc\Controller\AbstractActionController;
    use Zend\View\Model\ViewModel;
    use Issue\Model\Issue;
    use Issue\Form\IssueForm;
    
    class IssueController extends AbstractActionController
    {
        protected $issueTable;
    
        public function indexAction()
        {
            if (!$this->zfcUserAuthentication()->hasIdentity()) {
                return;
            }
            return new ViewModel(
                array(
                    'issues' => $this->getIssueTable()->fetchAll(
                        $this->zfcUserAuthentication()->getIdentity()->getId()
                    ),
                )
            );
        }
    
        public function addAction()
        {
            if (!$this->zfcUserAuthentication()->hasIdentity()) {
                return $this->redirect()->toRoute('issue');
            }
            $form = new IssueForm();
            $form->get('submit')->setValue('Add');
            $request = $this->getRequest();
            if ($request->isPost()) {
                $issue = new Issue();
                $form->setInputFilter($issue->getInputFilter());
                $form->setData($request->getPost());
                if ($form->isValid()) {
                    $issue->exchangeArray($form->getData());
                    $this->getIssueTable()->saveIssue(
                        $issue,
                        $this->zfcUserAuthentication()->getIdentity()->getId()
                    );
                    // Redirect to list of issues
                    return $this->redirect()->toRoute('issue');
                }
            }
            return array('form' => $form);
        }
    
        public function editAction()
        {
            if (!$this->zfcUserAuthentication()->hasIdentity()) {
                return $this->redirect()->toRoute('issue');
            }
            $id = (int)$this->params()->fromRoute('id', 0);
            if (!$id) {
                return $this->redirect()->toRoute(
                    'issue', array(
                    'action' => 'add'
                )
                );
            }
            // Get the Issue with the specified id.  An exception is thrown
            // if it cannot be found, in which case go to the index page.
            try {
                $issue = $this->getIssueTable()->getIssue($id);
            } catch (\Exception $ex) {
                return $this->redirect()->toRoute(
                    'issue', array(
                    'action' => 'index'
                )
                );
            }
            $form = new IssueForm();
            $form->bind($issue);
            $form->get('submit')->setAttribute('value', 'Edit');
            $request = $this->getRequest();
            if ($request->isPost()) {
                $form->setInputFilter($issue->getInputFilter());
                $form->setData($request->getPost());
                if ($form->isValid()) {
                    $this->getIssueTable()->saveIssue(
                        $issue,
                        $this->zfcUserAuthentication()->getIdentity()->getId()
                    );
                    // Redirect to list of issues
                    return $this->redirect()->toRoute('issue');
                }
            }
            return array(
                'id'   => $id,
                'form' => $form,
            );
        }
    
        public function deleteAction()
        {
            if (!$this->zfcUserAuthentication()->hasIdentity()) {
                return $this->redirect()->toRoute('issue');
            }
            $id = (int)$this->params()->fromRoute('id', 0);
            if (!$id) {
                return $this->redirect()->toRoute('issue');
            }
            $request = $this->getRequest();
            if ($request->isPost()) {
                $del = $request->getPost('del', 'No');
                if ($del == 'Yes') {
                    $id = (int)$request->getPost('id');
                    $this->getIssueTable()->deleteIssue($id);
                }
                // Redirect to list of issues
                return $this->redirect()->toRoute('issue');
            }
            return array(
                'id'    => $id,
                'issue' => $this->getIssueTable()->getIssue($id)
            );
        }
    
        public function getIssueTable()
        {
            if (!$this->issueTable) {
                $sm = $this->getServiceLocator();
                $this->issueTable = $sm->get('Issue\Model\IssueTable');
            }
            return $this->issueTable;
        }
    }
    
    0 讨论(0)
提交回复
热议问题