ZF3 Bootstrap上的单元测试认证

2024-01-05

我在为我的设备运行单元测试时遇到问题IndexController class.

单元测试仅执行以下操作(灵感来自zf3单元测试教程 https://docs.zendframework.com/tutorials/unit-testing/#your-first-controller-test):

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

In the Module.php我有一些功能来检查是否有用户登录,否则他将被重定向到login route.

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

The checkPermission方法只是检查用户角色和匹配的路由是否在acl存储中。 如果失败,我将重定向状态代码 404。

Problem:单元测试失败:“断言响应代码失败”200,实际状态代码为“302” 因此,单元测试从我的中跳入 else 情况onBootstrap方法中的Module.php重定向发生的地方。

我做了以下事情setUp in the TestCase但它不起作用:

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

非常感谢提示

该代码可能与以下内容略有不同Zend 框架 2但如果你在 zf2 中有一个简单的工作示例,也许我可以将其转换为 zf3 风格。

我不使用 ZfcUser - 只是使用 zend-acl / zend-authentication 东西


经过几天的头痛,我找到了一个可行的解决方案。

首先,我将所有代码移至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
}

Now my onBootstrap变得非常小,就像 ZF 想要的那样。文档参考 https://zendframework.github.io/zend-modulemanager/best-practices/#keep-the-init-and-onbootstrap-methods-lightweight

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);
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ZF3 Bootstrap上的单元测试认证 的相关文章

  • 如何使用多个分隔符拆分列表?

    基本上 我想在文本区域中输入文本 然后使用它们 例如 variable1 variable2 variable3 variable1 variable2 variable3 variable1 variable2 variable3 我知道
  • SplFileObject + LimitIterator + 偏移量

    我有两行数据文件 两行仅用于我的示例 实际上 该文件可以包含数百万行 并且我使用 SplFileObject 和 LimitIterator 进行偏移 但这种组合在某些情况下会有奇怪的行为 offset 0 file new SplFile
  • file_get_contents 获取 php 内容!我需要 html 中的源代码

    我正在尝试使用 file get contents 获取 php 文件的 html 内容 但我无法管理它 无论我做什么 它都需要 php 内容 所以我希望您理解并可以帮助我 脚本的代码
  • Woocommerce 从 woocommerce_add_to_cart_fragments 传回的错误片段

    我正在创建自定义 WooCommerce 购物车 并且更新购物车商品的数量工作正常 唯一的问题是它不会自动刷新 只有在页面加载后才起作用 我当前的代码使用woocommerce add to cart fragments挂钩并使用传入的 f
  • 如何在 PhpStorm 中为 PHPUnit 设置 HHVM

    如何使用 HHVM 作为解释器在 PhpStorm 8 中运行单元测试 PhpStorm 8 支持 PHPUnit 4 它支持 HHVM 我可以使用 HHVM 在 termianl 上运行我的测试套件 但我不知道如何配置 PhpStorm
  • PHP 下载页面

    这些 PHP 下载页面 例如 somesite com download php id somefile 通常如何工作 我最初想到了一个执行计数器操作的页面 然后简单地将用户重定向到文件 URL 这似乎是其他地方给出的唯一答案 但是我不知道
  • 下一个验证 |当用户对象有太多项目时,会话请求没有数据

    我会尽力为我解释我的问题 我使用 Strapi 作为后端 使用 Nextjs 作为前端 对于身份验证 我使用 NextAuth nextauth js const options providers Providers Credential
  • 查找所有具有相同值的数组键

    当值未知时 是否有一种更简单的方法来获取具有相同值的所有数组键 The problem with array unique是它返回唯一的数组 因此它找不到唯一的值 例如 从这个数组 Array a gt 1000 b gt 1 c gt 1
  • 使 Web 表单输入在各种情况下安全的正确方法是什么?

    你们都认为什么是正确的 阅读 最灵活 松散耦合 最健壮等 方法来使来自 Web 的用户输入安全地用于 Web 应用程序的各个部分 显然 我们可以为每个上下文 数据库 屏幕显示 保存在磁盘上等 使用各自的清理功能 但是是否有一些通用的 模式
  • 解决错误 413 请求实体太大

    我正在从事的项目允许我们的员工将大文件上传到我们的共享主机并获取下载链接 问题是我们的托管拒绝更改共享托管的 LimitRequestBody 还有其他解决方案可以解决 LimitRequestBody 或任何其他方法来完成这项工作吗 有两
  • 身份验证后如何退出 Google

    所以我的应用程序可以选择使用 Google 登录 单击 Google 提供的按钮后 将打开一个 Web 视图并让用户输入其凭据 允许应用程序访问其信息后 应用程序将用户登录并将 SignInViewController 更改为 TabBar
  • 带 Expect 的 Telnet 自动化:身份验证速度慢?

    我正在使用 Telnet 向 Mikrotik 路由器发送命令 telnet 192 168 100 100 l admin Password pass1234 admin ZYMMA gt interface pppoe server r
  • 终端从包含空格的变量传递参数

    在终端中如何将包含空格的字符串作为参数传递 它实际上跳过了空格后面的部分 只取第一个单词 word soccer ball shell exec casperjs test js word word 那么我怎样才能转义空白它只运行这个命令
  • 无法使用symfony2连接数据库oracle

    我需要的 我需要将oracle数据库与symfony2连接 我已经通过 php m 检查过 oci8 pdo odbc odbc 这是我关注的链接https gist github com johnkary 6481664 https gi
  • Razorpay 支付集成 -> 我如何检测关闭按钮 X 附近的 razorpay 模型

    我在 CI 框架中使用 Razorpay 当用户在没有付款的情况下关闭时 创建 razor 支付模型 然后对于取消订单 我希望通过状态更改为已取消来触发查询 那么我怎样才能检测到这一点 我已经在使用 by click jQuery 点击关闭
  • 访问php数组内部[关闭]

    Closed 这个问题需要调试细节 help minimal reproducible example 目前不接受答案 我有一个像这样的数组打印 array 2 systems gt array 5 1 gt string 1 1111 2
  • 如何反转散列和加盐密码? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我正在使用 vBulletin 登录使用它来交叉引用数据库 md5 md5 pass salt 我如何制作一个 PHP 脚本 以便每个密码
  • 如何在 Yii 框架中从数据库中获取所有表名和列名

    我正在开发一个模块 我想在其中执行动态相关下拉表和列名称功能 前任 获取所有表名称并将其显示在下拉字段中 选择特定表后 我想在下拉字段中再次显示其所有列名称 问题是 1 如何从数据库中获取所有表名 2 如何从表中获取所有列名 我尝试了一些文
  • 以编程方式添加数字签名外观?

    我正在以编程方式对我的 PDF 文件进行签名 并且我想将签名外观添加到 PDF 我需要哪些对象才能实现此目的 我知道我必须Annotations BBox and XObject但我真的不知道按什么顺序以及是否需要其他东西 调试此类内容以找
  • Codeigniter,为MySQL创建表和用户

    我想以编程方式使用 CI 创建数据库和用户 到目前为止 我有这 2 个简单的 MySQL 语句 CREATE DATABASE testdb DEFAULT CHARACTER SET utf8 COLLATE utf8 general c

随机推荐