首页 > 解决方案 > Laravel6 + AdminLTE3 我想知道为什么左侧菜单的授权测试只有在某些情况下才会失败

问题描述

概括

我想测试一下AdminLTE3(jeroennoten/laravel-adminlte)左侧菜单的显示,所以写了下面两个测试。

如果你只运行其中一个测试,它会成功,但如果你连续运行它们,它会失败。

第二个测试将以 A->B 或 B->A 的顺序失败。

如果您将测试方法分开,则每种方法都会成功。

我想知道为什么我不能将两者都放在一种测试方法中。

由于我在创建 Laravel 项目后立即安装了 AdminLTE3 并确认了上述现象,很难相信我的代码正在影响它。很难相信我自己的代码正在影响它。

版本/环境

作曲家.json

"jeroennoten/laravel-adminlte": "^3.5",
"laravel/framework": "^6.20",

确认

确认 结果
如果您实际以普通用户身份登录,请注销,然后以管理员用户身份登录。 工作正常。
如果两者都使用,测试目标(HomeController)会被调用两次吗? 它被调用了两次。
如果两者都使用,“Gate::define('system-only',~~”的内容会被调用两次吗? 它只被调用一次。原因不明。

代码

侧边菜单部分的代码(摘录)

adminlte.php

<?php
//omitted
[
    'text'        => 'Test',
    'url'         => 'admin/pages',
    'icon'        => 'far fa-fw fa-file',
    'label'       => 4,
    'label_color' => 'success',
    'can'         => 'system-only'
],
//omitted

授权部分

AuthServiceProvider.php

<?php
namespace App\Providers;

use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Gate;

class AuthServiceProvider extends ServiceProvider
{
    protected $policies = [
        // 'App\Model' => 'App\Policies\ModelPolicy',
    ];

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

        Gate::define("system-only", function ($user) {
            return $user->is_admin == 1;
        });
    }
}

测试目标

家庭控制器.php

<?php
namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;

class HomeController extends Controller
{
    public function index()
    {
        return view("admin.home");
    }
}

主页.blade.php

@extends('adminlte::page')

@section('title', 'Dashboard')

@section('content_header')
    <h1>Dashboard</h1>
@stop

@section('content')
    <p>Welcome to this beautiful admin panel.</p>
@stop

@section('css')
    <link rel="stylesheet" href="/css/admin_custom.css">
@stop

@section('js')
    <script> console.log('Hi!'); </script>
@stop

测试代码(失败的例子)

<?php
namespace Tests\Feature\Admin;

use App\User;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Tests\TestCase;

class HomeControllerTest extends TestCase
{
    use DatabaseTransactions;

    protected $url = "/admin/home";

    public function testIndex()
    {
        $normalUser = factory(User::class)->create([
            "id"       => 1,
            "is_admin" => 0
        ]);
        $adminUser = factory(User::class)->create([
            "id"       => 2,
            "is_admin" => 1
        ]);

        $this->actingAs($adminUser)
             ->get($this->url)
             ->assertSuccessful()
             ->assertSee("Test");

        $this->actingAs($normalUser)
             ->get($this->url)
             ->assertSuccessful()
             ->assertDontSee("Test");//failed
    }
}

测试代码(成功示例)

<?php
//omitted

//I just split the testIndex into two.
public function testIndexNormal()
{
    $normalUser = factory(User::class)->create([
        "id"       => 1,
        "is_admin" => 0
    ]);

    $this->actingAs($normalUser)
         ->get($this->url)
         ->assertSuccessful()
         ->assertDontSee("Test");
}

public function testIndexAdmin()
{
    $adminUser = factory(User::class)->create([
        "id"       => 2,
        "is_admin" => 1
    ]);

    $this->actingAs($adminUser)
         ->get($this->url)
         ->assertSuccessful()
         ->assertSee("Test"); 
}
//omitted

标签: phplaravelphpunitadminlte

解决方案


推荐阅读