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

Laravel功能测试中actingAs异常,关联返回null报错求助

问题描述

出现错误提示:

App\Models\User::team must return a relationship instance, but "null" was returned. Was the "return" keyword used?

场景为电商系统订单功能测试用例编写,相关代码如下:

User模型代码

public function team(): BelongsTo|null
{
    if (!empty($this->team_id)) {
        return $this->belongsTo(Team::class);
    }
    return null;
}

测试用例代码

public function test_order_status_update()
{
    $order = $this->create_order($this->books->id, $this->appUser->id, $this->address->id);
    $response = $this->actingAs($this->user)->put('orders/' . $order->json('order.id'), [
        'order_status' => 'ordered',
    ]);
    $response->assertRedirect('orders/' . $order->json('order.id'))->assertSessionHas('success');
}

权限中间件代码

public function handle(Request $request, Closure $next)
{
    //teams 1-Developer 2-Admin 3-Management 4-Marketing 5-Audit 6-Sales 7-Bookstores 8-Delivery 9-User
    $team = $request->user()->team;
    if ($team->id == 1 || $team->id == 2) {
        return $next($request);
    }
    $pages =  auth()->user()->pages->merge(auth()->user()->team->pages);
    $currentRouteName = $request->route()->getName();
    $pages->contains('route_name', $currentRouteName) ?: abort(403);
    return $next($request);
}

用户怀疑actingAs无法获取认证用户信息导致测试失败,寻求修复方案。

修复方案

1. 修正User模型的team关系方法

Laravel Eloquent的关系方法必须始终返回关系实例,不能返回null。直接定义关系即可,Laravel会自动处理team_id为空的场景,此时访问$user->team会得到null,但关系方法本身符合框架要求:

public function team(): BelongsTo
{
    return $this->belongsTo(Team::class);
}

2. 确保测试用户关联合法团队

测试失败的核心原因是$this->user的team_id为空,导致中间件访问$team->id时触发错误。需在测试前置环节为用户分配合法团队:

public function setUp(): void
{
    parent::setUp();
    
    // 创建管理员团队(对应中间件中允许直接通过的角色)
    $adminTeam = Team::factory()->create(['id' => 2]);
    // 给测试用户关联该团队
    $this->user = User::factory()->create(['team_id' => $adminTeam->id]);
}

3. 优化中间件的空值校验

为避免用户无团队导致的报错,在中间件中增加空值检查:

public function handle(Request $request, Closure $next)
{
    $user = $request->user();
    if (!$user) {
        abort(401); // 未登录用户直接返回未授权
    }
    
    $team = $user->team;
    if (!$team) {
        abort(403); // 无团队用户直接拒绝访问
    }
    
    if ($team->id == 1 || $team->id == 2) {
        return $next($request);
    }
    
    // 处理pages关联为空的情况
    $pages = $user->pages ?? collect();
    $pages = $pages->merge($team->pages ?? collect());
    
    $currentRouteName = $request->route()->getName();
    if (!$pages->contains('route_name', $currentRouteName)) {
        abort(403);
    }
    
    return $next($request);
}

内容的提问来源于stack exchange,提问作者Himanshu Rahi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 17:39:20