2013-01-16 19 views
8

Tôi đang gặp sự cố khi thử nghiệm đơn vị một hành động sử dụng ZfcUser để xác thực. Tôi cần một số cách để giả lập các plugin điều khiển ZfcUser nhưng tôi không chắc chắn như thế nào để làm điều này. Tôi đã quản lý thành công để tạo ra một số xét nghiệm đơn vị cho các bảng và mô hình nhưng bộ điều khiển đòi hỏi rất nhiều đối tượng được tiêm và đang gây ra vấn đề. Có ai biết làm thế nào để thiết lập các ZfcUser mocks để thành công đơn vị kiểm tra một bộ điều khiển?Kiểm tra đơn vị ZF2 đơn giản cho bộ điều khiển sử dụng ZfcUser

Đây là thử nghiệm của tôi (sao chép từ các hướng dẫn ZF2):

<?php 
namespace SmsTest\Controller; 

use SmsTest\Bootstrap; 
use Sms\Controller\SmsController; 
use Zend\Http\Request; 
use Zend\Http\Response; 
use Zend\Mvc\MvcEvent; 
use Zend\Mvc\Router\RouteMatch; 
use Zend\Mvc\Router\Http\TreeRouteStack as HttpRouter; 
use PHPUnit_Framework_TestCase; 

class SmsControllerTest extends PHPUnit_Framework_TestCase 
{ 
    protected $controller; 
    protected $request; 
    protected $response; 
    protected $routeMatch; 
    protected $event; 

    protected function setUp() 
    { 

     $serviceManager = Bootstrap::getServiceManager(); 

     $this->controller = new SmsController(); 
     $this->request = new Request(); 
     $this->routeMatch = new RouteMatch(array('controller' => 'index')); 
     $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); 
    } 


    /* Test all actions can be accessed */ 

    public function testIndexActionCanBeAccessed() 
    { 
     $this->routeMatch->setParam('action', 'index'); 

     $result = $this->controller->dispatch($this->request); 
     $response = $this->controller->getResponse(); 

     $this->assertEquals(200, $response->getStatusCode()); 
    } 
} 

Tôi đã thử các sau đây trong các phương pháp thiết lập:

$mockAuth = $this->getMock('ZfcUser\Entity\UserInterface'); 


    $authMock = $this->getMock('Zend\Authentication\AuthenticationService'); 
    $authMock->expects($this->any()) 
     ->method('hasIdentity') 
     ->will($this->returnValue(true)); 

    $authMock->expects($this->any()) 
     ->method('getIdentity') 
     ->will($this->returnValue(array('user_id' => 1))); 

Nhưng tôi không chắc chắn làm thế nào để tiêm này trong cho cá thể bộ điều khiển.

Hãy giả vờ mã hành động chỉ số của tôi chỉ là như sau:

public function indexAction() { 
    //Check if logged in 
    if (!$this->zfcUserAuthentication()->hasIdentity()) { 
     return $this->redirect()->toRoute('zfcuser/login'); 
    } 

    return new ViewModel(array(
     'success' => true, 
    )); 
} 

Kết quả thử nghiệm:

1) SmsTest\Controller\SmsControllerTest::testIndexActionCanBeAccessed 
Zend\ServiceManager\Exception\ServiceNotFoundException: Zend\ServiceManager\ServiceManager::get was unable to fetch or create an instance for zfcUserAuthentication 

/var/www/soap-app.localhost/Zend/vendor/zendframework/zendframework/library/Zend/ServiceManager/ServiceManager.php:450 
/var/www/soap-app.localhost/Zend/vendor/zendframework/zendframework/library/Zend/ServiceManager/AbstractPluginManager.php:110 
/var/www/soap-app.localhost/Zend/vendor/zendframework/zendframework/library/Zend/Mvc/Controller/PluginManager.php:90 
/var/www/soap-app.localhost/Zend/vendor/zendframework/zendframework/library/Zend/Mvc/Controller/AbstractController.php:276 
/var/www/soap-app.localhost/Zend/vendor/zendframework/zendframework/library/Zend/Mvc/Controller/AbstractController.php:291 
/var/www/soap-app.localhost/Zend/module/Sms/src/Sms/Controller/SmsController.php:974 
/var/www/soap-app.localhost/Zend/module/Sms/src/Sms/Controller/SmsController.php:974 
/var/www/soap-app.localhost/Zend/module/Sms/src/Sms/Controller/SmsController.php:158 
/var/www/soap-app.localhost/Zend/vendor/zendframework/zendframework/library/Zend/Mvc/Controller/AbstractActionController.php:87 
/var/www/soap-app.localhost/Zend/vendor/zendframework/zendframework/library/Zend/EventManager/EventManager.php:468 
/var/www/soap-app.localhost/Zend/vendor/zendframework/zendframework/library/Zend/EventManager/EventManager.php:208 
/var/www/soap-app.localhost/Zend/vendor/zendframework/zendframework/library/Zend/Mvc/Controller/AbstractController.php:108 
/var/www/soap-app.localhost/Zend/module/Sms/test/SmsTest/Controller/SmsControllerTest.php:57 

Dòng gây ngoại lệ này là bộ điều khiển là: nếu (!$this->zfcUserAuthentication()->hasIdentity()) { dòng đó liên quan đến dòng 974 trong SmsController.

Rõ ràng là tôi không có quyền truy cập vào dịch vụ ZfcUserAuthentication, do đó, câu hỏi là, Làm cách nào để thử dịch vụ ZfcUserAuthentication và đưa nó vào Bộ điều khiển của tôi?

Để tiếp tục chủ đề, tôi sẽ làm cách nào để mocking một người dùng đã đăng nhập để thử nghiệm thành công hành động của tôi đang hoạt động để chỉ định?

Trả lời

10

Tài liệu ZfcUser đề xuất rằng đây là plugin nên bạn cần phải tiêm phần này vào bộ điều khiển.

Bạn sẽ cần phải sửa đổi tên lớp của bạn để chọn lên các lớp ZfcUser

mocks của bạn cũng sẽ cần phải được addapted như getIdenty trả về một đối tượng khác nhau.

Làm việc sau đây cho tôi - chèn vào phương thức setup() phpunit của bạn.

$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); 

Có thể có cách dễ dàng hơn để chào đón những suy nghĩ khác.

0

Đây là cách tôi đã làm.

<?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; 
    } 
}