2016-08-22 5 views
2

IndexController 클래스에 대해 단위 테스트를 실행하는 데 문제가 있습니다.ZF3 부트 스트랩의 단위 테스트 인증

단위 테스트는 단지합니다 (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); 
    } 
} 

사용자 역할과 유사한 경로 ACL에 저장하는 경우에있어서 checkPermission 단지 확인한다. 이 난 404

문제 상태 코드를 리디렉션 실패하면 단위 테스트가 실패 "의 응답 코드를 어서 실패"200 302 " 따라서 단위 테스트는으로 점프"실제 상태 코드는 " . 리디렉션이 일어나는 Module.phponBootstrap 방식과 다른 경우

나는 그것은 다음 TestCase에setUp하지만 작동하지 않습니다 않았다

public function setUp() 
{ 
    // override default configuration values 
    $configOverrides = []; 

    $this->setApplicationConfig(ArrayUtils::merge(
     include __DIR__ . '/../../../../config/application.config.php', 
     $configOverrides 
    )); 

    $user = new Employee(); 
    $user->id = 1; 
    $user->system_name = 'admin'; 
    $user->role = 'Admin'; 

    $this->authService = $this->prophesize(AuthService::class); 
    $auth = $this->prophesize(AuthenticationService::class); 
    $auth->hasIdentity()->willReturn(true); 
    $auth->getIdentity()->willReturn($user); 

    $this->authService->getAuth()->willReturn($auth->reveal()); 

    $this->getApplicationServiceLocator()->setAllowOverride(true); 
    $this->getApplicationServiceLocator()->setService(AuthService::class, $this->authService->reveal()); 
    $this->getApplicationServiceLocator()->setAllowOverride(false); 

    parent::setUp(); 
} 

힌트는 매우 젠드 프레임 워크 2에서 약간 다를 수 있습니다

코드

을 감사합니다하지만 당신은 zf2에서 간단한 동작하는 예제가 있다면 어쩌면 내가 zf3 스타일로 변환 할 수 있습니다.

나는 ZfcUser를 사용하지 않습니다 - 단지 젠드 - ACL/젠드 인증 물건

답변

3

을 내가 작업 솔루션을 가지고 두통의 몇 일 후.

처음에는 onBootstrap 내의 모든 코드를 Listener로 옮겼습니다. phpunit mocks가 zf 부트 스트랩 후 생성되어 내 유닛 테스트에 존재하지 않기 때문입니다.

열쇠는 zf가 부트 스트랩을 마친 후에 호출되는 호출 가능한 리스너 메소드에서 서비스가 생성된다는 것입니다. 그러면 PHPUnit은 제공된 모의로 서비스를 무효화 할 수 있습니다.

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 
} 

AuthenticationListener

지금 내 onBootstrap는 ZF가 원하는 것처럼 정말 작은 얻었다.

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

documentation reference

Module.php 마지막으로 단위 테스트 내 조롱은 다음과 같습니다

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