php - 在测试 Laravel 应用程序时,一个加载门如何定义?

标签 php laravel testing laravel-5

我正在为 Laravel 应用程序编写测试。在我的 AuthServiceProvider->boot() 中,我根据数据库中的权限表使用 $gate->define() 定义了许多用户能力。

基本上是这样的:

 foreach ($this->getPermissions() as $permission) {
            $gate->define($permission->name, function ($user) use ($permission) {
                return $user->hasPermission($permission->name);
            });
        }

在我的测试中,我正在动态创建权限,但是 AuthServiceProvider 已经启动,这意味着我无法使用 @can 验证用户权限,

有没有合适的方法来处理这个问题?

最佳答案

我知道我在这个问题上迟到了一点,但我自己也遇到了同样的问题,因此这个问题没有一个全面的答案,这是我对同一问题的解决方案(在Laravel 5.3):

我在我的 app\Providers\AuthServiceProvider 中有这个:

/**
 * Register any authentication / authorization services.
 *
 * @param Gate $gate
 */
public function boot(Gate $gate)
{
    $this->registerPolicies();

    if (!app()->runningInConsole()) {
        $this->definePermissions($gate);
    }
}

/**
 * @param Gate $gate
 */
private function definePermissions(Gate $gate)
{
    $permissions = Permission::with('roles')->get();

    foreach($permissions as $permission) {
        $gate->define($permission->key, function($user) use ($permission) {
            return $user->hasRole($permission->roles);
        });
    }
}

这会在测试时处理正常的应用程序流程,并在测试时禁用过早的策略注册。

在我的 tests/TestCase.php 文件中,我定义了以下方法(注意 Gate 指向 Illuminate\Contracts\Auth\Access\Gate):

/**
 * Logs a user in with specified permission(s).
 *
 * @param $permissions
 * @return mixed|null
 */
public function loginWithPermission($permissions)
{
    $user = $this->userWithPermissions($permissions);

    $this->definePermissions();

    $this->actingAs($user);

    return $user;
}

/**
 * Create user with permissions.
 *
 * @param $permissions
 * @param null $user
 * @return mixed|null
 */
private function userWithPermissions($permissions, $user = null)
{
    if(is_string($permissions)) {
        $permission = factory(Permission::class)->create(['key'=>$permissions, 'label'=>ucwords(str_replace('_', ' ', $permissions))]);

        if (!$user) {
            $role = factory(Role::class)->create(['key'=>'role', 'label'=>'Site Role']);

            $user = factory(User::class)->create();
            $user->assignRole($role);
        } else {
            $role = $user->roles->first();
        }

        $role->givePermissionTo($permission);
    } else {
        foreach($permissions as $permission) {
            $user = $this->userWithPermissions($permission, $user);
        }
    }

    return $user;
}

/**
 * Registers defined permissions.
 */
private function definePermissions()
{
    $gate = $this->app->make(Gate::class);
    $permissions = Permission::with('roles')->get();

    foreach($permissions as $permission) {
        $gate->define($permission->key, function($user) use ($permission) {
            return $user->hasRole($permission->roles);
        });
    }
}

这使我能够以多种方式在测试中使用它。考虑我的 tests/integration/PermissionsTest.php 文件中的用例:

/** @test */
public function resource_is_only_visible_for_those_with_view_permission()
{
    $this->loginWithPermission('view_users');
    $this->visit(route('dashboard'))->seeLink('Users', route('users.index'));
    $this->visit(route('users.index'))->assertResponseOk();

    $this->actingAs(factory(User::class)->create());
    $this->visit(route('dashboard'))->dontSeeLink('Users', route('users.index'));
    $this->get(route('users.index'))->assertResponseStatus(403);
}

/** @test */
public function resource_action_is_only_visible_for_those_with_relevant_permissions()
{
    $this->loginWithPermission(['view_users', 'edit_users']);
    $this->visit(route('users.index'))->seeLink('Edit', route('users.edit', User::first()->id));

    $this->loginWithPermission('view_users');
    $this->visit(route('users.index'))->dontSeeLink('Edit', route('users.edit', User::first()->id));
}

这在我的所有测试中都运行良好。希望对您有所帮助。

关于php - 在测试 Laravel 应用程序时,一个加载门如何定义?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33110073/

相关文章:

wcf - 单元测试 LinqToSqlDomainService

php - sql查询需要从另一个表输入

php - 为暂停的 Woocommerce 订单发送客户处理订单电子邮件通知

php - Laravel - 关于如何找出用户上次登录的架构

php - 如何用 Eloquent 方式在数据透视表中获取具有特定属性的所有项目?

java - 使用 mockito 和 spring 测试服务

php - 如何从不同的特定类别中获取随机数量的最新记录并按类别排序?

php - XML 到 sql 数据库

php - Laravel - 下拉 Pluck 数据无法获取字符串值

java - 如何修复 : java. lang.ClassNotFoundException : BasicSimulation for gradle gatlingRun task?