标签:authentication zend-framework3 phpunit php
我在为我的IndexController类运行单元测试时遇到问题.
单元测试仅执行以下操作(启发自unit-test tutorial of zf3):
IndexControllerTest.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');
}
在Module.php中,我具有一些功能来检查是否有用户登录,否则他将被重定向到登录路径.
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方法跳转到else情况.
我在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();
}
Hints are very appreciated
该代码可能与Zend Framework 2有所不同,但是如果您在zf2中有一个简单的工作示例,也许我可以将其转换为zf3样式.
我不使用ZfcUser-只是zend-acl / zend-authentication的东西
解决方法:
经过几天的头痛,我有了一个可行的解决方案.
首先,我将onBootstrap中的所有代码移到了侦听器,因为phpunit模拟是在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
}
现在,我的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);
}
标签:authentication,zend-framework3,phpunit,php 来源: https://codeday.me/bug/20191118/2026869.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。