2016-08-22 9 views
2

IndexControllerクラスでユニットテストを実行する際に問題が発生しました。ZF3ユニットテスト認証onBootstrap

ユニットテストがちょうど(unit-test tutorial of zf3からインスピレーションを得た)以下のん:

IndexControllerTest.php

私は、ユーザーがあるかどうかを確認するためにいくつかの機能が他の、ログインしてきた Module.php
public function testIndexActionCanBeAccessed() 
{ 
    $this->dispatch('/', 'GET'); 
    $this->assertResponseStatusCode(200); 
    $this->assertModuleName('main'); 
    $this->assertControllerName(IndexController::class); // as specified in router's controller name alias 
    $this->assertControllerClass('IndexController'); 
    $this->assertMatchedRouteName('main'); 
} 

彼はloginルートにリダイレクトされます。

Module.php

public function onBootstrap(MvcEvent $mvcEvent) 
{ 
    /** @var AuthService $authService */ 
    $authService = $mvcEvent->getApplication()->getServiceManager()->get(AuthService::class); 
    $this->auth = $authService->getAuth(); // returns the Zend AuthenticationService object 

    // store user and role in global viewmodel 
    if ($this->auth->hasIdentity()) { 
     $curUser = $this->auth->getIdentity(); 
     $mvcEvent->getViewModel()->setVariable('curUser', $curUser['system_name']); 
     $mvcEvent->getViewModel()->setVariable('role', $curUser['role']); 
     $mvcEvent->getApplication()->getEventManager()->attach(MvcEvent::EVENT_ROUTE, [$this, 'checkPermission']); 
    } else { 
     $mvcEvent->getApplication()->getEventManager()->attach(MvcEvent::EVENT_DISPATCH, [$this, 'authRedirect'], 1000); 
    } 
} 

checkPermission方法ユーザーの役割と一致したルートがACLストレージにある場合だけチェックします。 これが失敗した場合、私は404

問題のステータスコードをリダイレクトする:ユニットテストが失敗:200「レスポンスコードアサート失敗 『302『 したがってユニットテストは、にジャンプ』、実際のステータスコードが』リダイレクトが起こるModule.phpの私onBootstrap方法から他のケース

私はのTestCaseで次setUpをしましたが、それは動作しません:。

​​3210 の

ヒントは非常にコードがZend Frameworkの2から少し異なる場合がありますが、あなたはZF2で簡単な作業例を持っている場合は、多分私はZF3スタイルにそれを変換することができ

を高く評価しています。

私はZfcUserを使用していない - 私は実用的なソリューションを持って頭痛の数日後にただのZend-ACL/Zendの認証のもの

答えて

3

最初に私はonBootstrap内のすべてのコードをリスナーに移動しました。これは、phpunitモックがzfブートストラップの後に生成され、そのためユニットテストでは存在しないためです。

キーは、zfがブートストラップを終了した後に呼び出されるコール可能なリスナメソッドでサービスが生成されることです。 PHPUnitは提供されたモックでサービスを無効にできます。

AuthenticationListener

class AuthenticationListener implements ListenerAggregateInterface 
{ 
use ListenerAggregateTrait; 

/** 
* @var AuthenticationService 
*/ 
private $auth; 

/** 
* @var Acl 
*/ 
private $acl; 

/** 
* Attach one or more listeners 
* 
* Implementors may add an optional $priority argument; the EventManager 
* implementation will pass this to the aggregate. 
* 
* @param EventManagerInterface $events 
* @param int $priority 
* 
* @return void 
*/ 
public function attach(EventManagerInterface $events, $priority = 1) 
{ 
    $this->listeners[] = $events->attach(MvcEvent::EVENT_ROUTE, [$this, 'checkAuthentication']); 
} 

/** 
* @param MvcEvent $event 
*/ 
public function checkAuthentication($event) 
{ 
    $this->auth = $event->getApplication()->getServiceManager()->get(AuthenticationService::class); 
    $aclService = $event->getApplication()->getServiceManager()->get(AclService::class); 
    $this->acl = $aclService->init(); 

    $event->getViewModel()->setVariable('acl', $this->acl); 
    if ($this->auth->hasIdentity()) { 
     $this->checkPermission($event); 
    } else { 
     $this->authRedirect($event); 
    } 
} 

// checkPermission & authRedirect method 
} 

今私のonBootstrapはZFがそれを望んでいるだけのように、本当に小さなました。documentation reference

Module.php

public function onBootstrap(MvcEvent $event) 
{ 
    $authListener = new AuthenticationListener(); 
    $authListener->attach($event->getApplication()->getEventManager()); 
} 

最後にユニットテストの私のモックは、次のようになります

IndexControllerTest

private function authMock() 
{ 
    $mockAuth = $this->getMockBuilder(AuthenticationService::class)->disableOriginalConstructor()->getMock(); 
    $mockAuth->expects($this->any())->method('hasIdentity')->willReturn(true); 
    $mockAuth->expects($this->any())->method('getIdentity')->willReturn(['id' => 1, 'systemName' => 'admin', 'role' => 'Admin']); 

    $this->getApplicationServiceLocator()->setAllowOverride(true); 
    $this->getApplicationServiceLocator()->setService(AuthenticationService::class, $mockAuth); 
    $this->getApplicationServiceLocator()->setAllowOverride(false); 
} 
関連する問題