You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel Nova测试如何避免重定向,直接验证页面存在?

Laravel Nova 页面存在性测试:绕过认证与权限校验问题

我正在给Laravel Nova Admin应用添加Pest和单元测试,只想验证页面是否存在,完全不想考虑用户认证、角色或权限这些条件。但测试Nova路由时总是被重定向到登录页,试过移除部分中间件、模拟授权用户都没用——前者返回302重定向到登录页,后者直接403禁止访问。怎么才能禁用重定向、绕过所有权限认证,直接测试页面内容?

失败的测试尝试1

class ExampleTest extends TestCase
{
    public function test_it_should_have_a_login_page()
    {
        $response = $this->get('/login');
        $response->assertStatus(200);  //<-- 这个测试通过
    }

    public function test_it_should_have_a_routing_resources_page()
    {
        $response = $this
                ->withoutMiddleware(\App\Http\Middleware\Authenticate::class)
                ->withoutMiddleware(\App\Http\Middleware\RedirectIfAuthenticated::class)
                ->withoutMiddleware(\App\Http\Middleware\VerifyCsrfToken::class)
                ->get('/resources/routing');
        $response->assertStatus(200);  //<-- 失败,返回302重定向到登录页
    }
}

失败的测试尝试2

public function test_it_should_have_a_routing_resources_page()
{
    $user = User::factory()->create();
    $role = NovaRole::create(['name' => 'admin', 'updated_at' => now(), 'created_at' => now(), 'slug' => 'admin']);
    $user->assignRole($role->name);
    $permissions = config('nova-permissions.permissions');
    foreach ($permissions as $permission) {
        $user->hasPermissionTo($permission);
    }

    $response = $this
            ->actingAs($user)
            ->withoutMiddleware(\App\Http\Middleware\Authenticate::class)
            ->withoutMiddleware(\App\Http\Middleware\RedirectIfAuthenticated::class)
            ->withoutMiddleware(\App\Http\Middleware\VerifyCsrfToken::class)
            ->get('/resources/routing');
    $response->assertStatus(200); //<-- 失败,返回403禁止访问
}

解决方案

Laravel Nova自身带有独立的中间件和授权控制,只移除应用层的中间件没用,得从Nova的核心校验入手:

1. 绕过Nova的认证中间件

Nova路由使用的是Laravel\Nova\Http\Middleware\Authenticate,而非你应用自定义的认证中间件,所以要移除这个Nova自带的中间件:

public function test_it_should_have_a_routing_resources_page()
{
    $response = $this
        ->withoutMiddleware(\Laravel\Nova\Http\Middleware\Authenticate::class)
        ->get('/resources/routing');
    $response->assertStatus(200);
}

2. 绕过Nova的权限校验(资源策略)

如果仍返回403,说明Nova的资源授权策略在生效。可以通过两种方式绕过:

全局禁用所有授权校验

在测试方法开头调用$this->withoutAuthorization();,这会绕过Laravel所有授权逻辑,包括Nova的资源策略:

public function test_it_should_have_a_routing_resources_page()
{
    $this->withoutAuthorization();
    $this->withoutMiddleware(\Laravel\Nova\Http\Middleware\Authenticate::class);
    
    $response = $this->get('/resources/routing');
    $response->assertStatus(200);
}

针对特定资源Mock策略校验

如果不想全局禁用授权,可单独Mock对应资源的策略类,让权限校验返回true:

use App\Nova\Routing;
use App\Policies\RoutingPolicy;

public function test_it_should_have_a_routing_resources_page()
{
    $this->withoutMiddleware(\Laravel\Nova\Http\Middleware\Authenticate::class);
    
    $this->mock(RoutingPolicy::class, function ($mock) {
        // 针对列表页,需要mock viewAny方法
        $mock->shouldReceive('viewAny')->andReturn(true);
        // 若测试详情页,需额外mock view方法,依此类推
    });
    
    $response = $this->get('/resources/routing');
    $response->assertStatus(200);
}

3. 移除Nova的其他校验中间件(可选)

如果还有Nova的Authorize中间件干扰,可一并移除:

public function test_it_should_have_a_routing_resources_page()
{
    $response = $this
        ->withoutMiddleware([
            \Laravel\Nova\Http\Middleware\Authenticate::class,
            \Laravel\Nova\Http\Middleware\Authorize::class,
        ])
        ->get('/resources/routing');
    $response->assertStatus(200);
}

内容的提问来源于stack exchange,提问作者Asa LeHolland

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 06:50:26