【问题标题】:Testing unauthorized user restriction in Laravel PHPUnit在 Laravel PHPUnit 中测试未经授权的用户限制
【发布时间】:2016-09-26 14:06:37
【问题描述】:

Laravel 5.2 版

在我的项目中,role_id = 4 的用户具有管理员角色,可以管理用户。

我在 AuthServiceProvider 中定义了以下能力:

public function boot(GateContract $gate)
{
    $this->registerPolicies($gate);

    $gate->define('can-manage-users', function ($user)
    {
        return $user->role_id == 4;
    });
}

我在UserController的__construct方法中使用了这个能力,如下:

public function __construct()
{
    $this->authorize('can-manage-users');
}

在 ExampleTest 中,我创建了两个测试来检查定义的授权是否有效。

对于 role_id = 4 的管理员用户的第一个测试。此测试通过。

public function testAdminCanManageUsers()
{
    $user = Auth::loginUsingId(1);
    $this->actingAs($user)
        ->visit('users')
        ->assertResponseOk();
}

第二个测试是针对另一个没有 role_id = 4 的用户。我尝试过响应状态为 401 和 403。但测试失败:

public function testNonAdminCannotManageUsers()
{
    $user = Auth::loginUsingId(4);
    $this->actingAs($user)
        ->visit('users')
        ->assertResponseStatus(403);
}

失败信息的前几行如下:

对 [http://localhost/users] 的请求失败。收到状态码 [403]。

C:\wamp\www\laravel\blog\vendor\laravel\framework\src\Illuminate\Foundation\Testing\Concerns\InteractsWithPages.php:196 C:\wamp\www\laravel\blog\vendor\laravel\framework\src\Illuminate\Foundation\Testing\Concerns\InteractsWithPages.php:80 C:\wamp\www\laravel\blog\vendor\laravel\framework\src\Illuminate\Foundation\Testing\Concerns\InteractsWithPages.php:61 C:\wamp\www\laravel\blog\tests\ExampleTest.php:33

由异常'Illuminate\Auth\Access\AuthorizationException'引起 带有消息“此操作未经授权。”在 C:\wamp\www\laravel\blog\vendor\laravel\framework\src\Illuminate\Auth\Access\HandlesAuthorization.php:28

我也尝试过如下使用'see'方法:

public function testNonAdminCannotManageUsers()
{
    $user = Auth::loginUsingId(4);
    $this->actingAs($user)
        ->visit('users')
        ->see('This action is unauthorized.');
}

但它也失败了。我究竟做错了什么?我怎样才能使测试通过?

【问题讨论】:

  • 这个问题有什么进展吗?

标签: php unit-testing laravel phpunit laravel-5.2


【解决方案1】:

至少从 Laravel 5.4 开始,您将需要使用 assertStatus(403) 方法。

public function testNonAdminCannotManageUsers()
{
    $user = Auth::loginUsingId(4);
    $this->actingAs($user)
        ->visit('users')
        ->assertStatus(403);
}

【讨论】:

    【解决方案2】:

    由于Auth 中间件在默认情况下未经身份验证时会重定向到登录路由,因此您还可以执行以下测试:

    public function testNonAdminCannotManageUsers()
    {
        $user = Auth::loginUsingId(4);
        $this->actingAs($user)
            ->visit('users')
            ->assertRedirect('login');
    }
    

    【讨论】:

      【解决方案3】:

      错误是调用visit 方法。 visit 方法在 InteractsWithPages 特征中。此方法调用makeRequest 方法,该方法又调用assertPageLoaded 方法。此方法获取返回的状态码,如果获取的代码不是 200,它会捕获 PHPUnitException 并抛出带有消息的 HttpException

      “对 [{$uri}] 的请求失败。收到状态代码 [{$status}]。”

      这就是测试失败并显示上述消息的原因。

      使用get方法代替visit方法可以成功通过测试。例如:

      public function testNonAdminCannotManageUsers()
      {
          $user = App\User::where('role_id', '<>', 4)->first();
      
          $this->actingAs($user)
              ->get('users')
              ->assertResponseStatus(403);
      }
      

      此测试将通过并确认非管理员用户无法访问该 url。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-09-29
        • 2019-12-01
        • 1970-01-01
        • 1970-01-01
        • 2018-01-05
        • 1970-01-01
        • 2018-12-11
        相关资源
        最近更新 更多