2016-11-07 7 views
0

私はZend Framework 3チュートリアルページに存在するユニットテストアルバムアプリの実装をしたいと思います。私は元の実装にいくつかの機能(loginとacl)を追加しました。私はzf3のユニットテストのチュートリアルに従いましたが、それに従うことができませんでした、どのように認証を模擬し、いくつかのテストケースを書きます。私のアルバムアプリの実装。ユニットテストZend Framework 3 Album App

Unit Testing Tutotial for zf3

AlbumController.php

<?php 
namespace Album\Controller; 

use Album\Model\AlbumTable; 
use Album\Model\LoginTable; 
use Album\Controller\LoginController; 
use Zend\Mvc\Controller\AbstractActionController; 
use Zend\View\Model\ViewModel; 
use Album\Form\AlbumForm; 
use Album\Model\Album; 
use Zend\Paginator\Adapter\Iterator as paginatorIterator; 
use Zend\Paginator\Paginator; 
use Zend\Db\Sql\Select; 
use Album\Form\SearchForm; 
use Zend\Session\Container; 
use Album\Utility\Acl; 
use \Zend\Mvc\MvcEvent; 

class AlbumController extends AbstractActionController 
{ 
    private $table; 
    protected $role; 
    public function __construct(AlbumTable $table){ 
    $this->table = $table; 
} 

public function onDispatch(MvcEvent $e) 
{ 
    $userSession = new Container('user'); 
    if (!isset($userSession->email)) { 
    return $this->redirect()->toRoute('login'); 
}else { 
    $this->role = $userSession->role; 
    parent::onDispatch($e); 
} 
} 
public function authorize($role,$action) 
{ 
    if($role == 'admin'){ 
    $acl = new Acl(); 
    if ($acl->isAllowed('admin', 'AlbumController', $action)) { 
     return true; 
    } 
} 
    return false; 
} 

public function indexAction(){ 
    $searchform = new SearchForm(); 
    $searchform->get('submit')->setValue('search'); 
    $select = new Select(); 
    $order_by = $this->params()->fromRoute('order_by') ?$this->params()->fromRoute('order_by') : 'id'; 
    $search=""; 
    $order = $this->params()->fromRoute('order') ?$this->params()->fromRoute('order') : Select::ORDER_ASCENDING; 
    $page = $this->params()->fromRoute('page') ? (int) $this->params()->fromRoute('page') : 1; 
    $request = $this->getRequest(); 
    if ($request->isGet()) 
    { 
     $formdata = (array) $request->getQuery(); 
     $search_data = array(); 
     foreach ($formdata as $key => $value) 
     { 
     if ($key != 'submit') 
     { 
     if (!empty($value)) 
     { 
      $search_data[$key] = $value; 
     } 
     } 
    } 
    if (!empty($search_data)) 
    { 
     $search = $search_data; 
    } 
    $searchform->setData($formdata); 
    } 
    $search_by = $this->params()->fromQuery() ? $this->params()->fromQuery() : ''; 
    $paginator = $this->table->fetchAll($order_by,$order,$search,$select); 
     $page = (int) $this->params()->fromQuery('page', 1); 
     $page = ($page < 1) ? 1 : $page; 
     $paginator->setCurrentPageNumber($page); 
     $paginator->setItemCountPerPage(10); 
     return new ViewModel([ 
    'search_by'=> $search_by, 
    'order_by' => $order_by, 
    'order' => $order, 
    'page' => $page, 
    'paginator' => $paginator, 
    'pageAction' => 'album', 
    'form'  => $searchform, 
    'flashMessages' => $this->flashMessenger()->getMessages(), 
    ]); 
} 
public function addAction() 
{ 
    $action = 'add'; 
    $permission = $this->authorize($this->role,$action); 
    if (!$permission) { 
    $this->flashMessenger()->addMessage('<div class="alert alert-danger" role="alert"><b>You dont have the privilege to add!!</b></div>'); 
    return $this->redirect()->toRoute('album'); 
} 

$form = new AlbumForm(); 
$form->get('submit')->setValue('Add'); 
$request = $this->getRequest(); 

if ($request->isPost()) { 
    $album = new Album(); 
    $form->setInputFilter($album->getInputFilter()); 
    $form->setData($request->getPost()); 
    $add = $request->getPost('submit', 'Cancel'); 

    if($add == 'Cancel'){ 
    $this->flashMessenger()->addMessage('<div class="alert alert-danger" role="alert"><b>Cancelled by User...!!</b></div>'); 
    return $this->redirect()->toRoute('album'); 
    } 

    if ($form->isValid()) { 
    $album->exchangeArray($form->getData()); 
    $this->table->saveAlbum($album); 
    $this->flashMessenger()->addMessage('<div class="alert alert-success" role="alert"><b>Added Successfully...</b></div>'); 
    }else { 
    $this->flashMessenger()->addMessage('<div class="alert alert-danger" role="alert"><b>Failed to Add...!!</b></div>'); 
    return array('form' => $form); 
    } 
    return $this->redirect()->toRoute('album'); 
} 
return array('form' => $form); 
} 

public function editAction() 
{ 
    $action = 'edit'; 
    $permission = $this->authorize($this->role,$action); 
    if (!$permission) { 
    $this->flashMessenger()->addMessage('<div class="alert alert-danger" role="alert"><b>You dont have the privilege to edit!!</b></div>'); 
    return $this->redirect()->toRoute('album'); 
} 
$id = (int) $this->params()->fromRoute('id', 0); 

if (0 === $id) { 
    return $this->redirect()->toRoute('album', ['action' => 'add']); 
} 
try { 
    $album = $this->table->getAlbum($id); 
}catch (\Exception $e) { 
    return $this->redirect()->toRoute('album', ['action' => 'index']); 
} 

$form = new AlbumForm(); 
$form->bind($album); 
$form->get('submit')->setAttribute('value', 'Edit'); 

$request = $this->getRequest(); 
$viewData = ['id' => $id, 'form' => $form]; 

if (! $request->isPost()) { 
    return $viewData; 
} 

$form->setInputFilter($album->getInputFilter()); 
$form->setData($request->getPost()); 
$edit = $request->getPost('submit', 'Cancel'); 

if($edit == 'Cancel'){ 
    $this->flashMessenger()->addMessage('<div class="alert alert-danger" role="alert"><b>Cancelled by User...!!</b></div>'); 
    return $this->redirect()->toRoute('album'); 
} 

if (! $form->isValid()) { 
    $this->flashMessenger()->addMessage('<div class="alert alert-danger" role="alert"><b>Failed to Update...!!</b></div>'); 
    return $viewData; 
}else{ 
    $this->table->saveAlbum($album); 
    $this->flashMessenger()->addMessage('<div class="alert alert-success" role="alert"><b>Record Updated Successfully...!!</b></div>'); 
} 
return $this->redirect()->toRoute('album', ['action' => 'index']); 
} 

public function deleteAction() 
{ 
$action = 'delete'; 
$permission = $this->authorize($this->role,$action); 
if (!$permission) { 
    $this->flashMessenger()->addMessage('<div class="alert alert-danger" role="alert"><b>You dont have the privilege to delete!!</b></div>'); 
    return $this->redirect()->toRoute('album'); 
} 

$id = (int) $this->params()->fromRoute('id', 0); 
if (!$id) { 
return $this->redirect()->toRoute('album'); 
} 
$request = $this->getRequest(); 
if ($request->isPost()) { 
$del = $request->getPost('del', 'No'); 
if ($del == 'Yes') { 
    $id = (int) $request->getPost('id'); 
    $this->table->deleteAlbum($id); 
    $this->flashMessenger()->addMessage('<div class="alert alert-success" role="alert"><b>Record Deleted Successfully...!!</b></div>'); 
}else{ 
    $this->flashMessenger()->addMessage('<div class="alert alert-danger" role="alert"><b>Failed to delete...!!</b></div>'); 
} 
return $this->redirect()->toRoute('album'); 
} 
return [ 
    'id' => $id, 
    'album' => $this->table->getAlbum($id), 
]; 
} 
} 

LoginController.php

<?php 

namespace Album\Controller; 

use Album\Form\LoginForm; 
use Album\Model\Login; 
use Album\Model\LoginTable; 
use Zend\Authentication\Adapter\DbTable as AuthAdapter; 
use Zend\Authentication\AuthenticationService; 
use Zend\Authentication\Result; 
use Zend\Mvc\Controller\AbstractActionController; 
use Zend\ServiceManager\ServiceLocatorInterface; 
use Zend\Session\Container; 
use Zend\Db\Adapter\Adapter as DbAdapter; 

class LoginController extends AbstractActionController 
{ 
    public $userSession; 
    public $loginTable; 
    public function __construct(LoginTable $loginTable) 
    { 
     $this->loginTable = $loginTable; 
    } 
public function loginAction() 
{ 
    $userSession = new Container('user'); 
    if(!isset($userSession->email)){ 
    $form = new LoginForm(); 
    $form->get('submit')->setValue('Login'); 

    $request = $this->getRequest(); 

    if ($request->isPost()){ 
     $login = new Login(); 
     $form->setInputFilter($login->getInputFilter()); 
     $form->setData($request->getPost()); 
     if ($form->isValid()) 
     { 
     $data=$form->getData(); 
     $dbAdapter = new DbAdapter(array(
      'driver'   => 'Pdo', 
      'dsn'   => 'mysql:dbname=customers;host=localhost;', 
      'username' => "root", 
      'password' => "", 
     )); 

      $authAdapter=new AuthAdapter($dbAdapter,'login','email','password'); 
        $authAdapter->setTableName('login')->setIdentityColumn('email')->setCredentialColumn('password'); 
        $authAdapter->setIdentity($data['email'])->setCredential($data['password']); 
      $auth=new AuthenticationService(); 
      $result = $auth->authenticate($authAdapter); 
      switch ($result->getCode()) 
         { 
        case Result::FAILURE_IDENTITY_NOT_FOUND: 
        break; 
        case Result::FAILURE_CREDENTIAL_INVALID: 
           break; 
        case Result::SUCCESS: 
        $userSession->email = $data['email']; 
        $row=$this->loginTable->getRow($userSession->email); 
        $userSession->role = $row['role']; 
        $this->flashMessenger()->addMessage('<div class="alert alert-success" role="alert"><b>Login Successful!!</b></div>'); 
           return $this->redirect()->toRoute('album', array('action' => 'index')); 
        default : 
        return $this->redirect()->toRoute('home'); 
        break; 
      } 
     } 
    } 
    return array('form' => $form,'fm' => $this->flashMessenger()->getMessages(),); 
    } 
    return $this->redirect()->toRoute('album'); 
} 

public function logoutAction(){ 
    $session = new Container('User'); 
    $session->getManager()->destroy(); 
    $auth=new AuthenticationService(); 
     $auth->clearIdentity(); 
    return $this->redirect()->toRoute('login'); 
} 
} 

答えて

1

ZFを使用すると、依存性の注入のために使用することができますservicemangerを持っています。 UserTableとLoginTableをコントローラに注入しているので、既に使用しています。コントローラやその他のサービスにオブジェクトを挿入する主な理由は、再利便性とテスト容易性です。これらの2つの注入サービスは簡単に嘲笑され、模擬バージョンはテスト中にこれらのクラスに注入できます。

コントローラ内またはそのアクション内でインスタンス化するすべてのオブジェクトをモックすることはできません。したがって、ACL、User sessionコンテナ、およびAuthenticationServiceをリファクタリングして取り出す必要があります。必要に応じてそれらの工場を書き、それらをサービスマンに追加してください。最後に必要な場所にコントローラに注入します。これで、あなたはそれらを模擬したり、各コンポーネントごとに個別のテストを書くことができます。

次の問題は、コントローラ内でデータベース接続を作成するクエリを構築することです。ここでも、データベース接続の作成はファクトリに入り、再利用して必要な場所に挿入することができます。クエリの作成はrepositoryになります。ユーザー名とパスワードはローカル設定ファイル(gitで無視されるもの)に入れてください。

ZendFrameworkは、これであなたを助けるためにmultiple packagesがあります

関連する問題