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

Laravel Sanctum下assertAuthenticatedAs断言测试异常原因咨询

Laravel Sanctum测试:assertAuthenticatedAs直接调用失败,带token请求后成功的原因

问题场景

我尝试用assertAuthenticatedAs方法验证用户是否已认证,该方法接收模型实例和guard参数,但直接执行测试时断言失败。

测试代码:

public function test_regsiter_a_user(): void
{
    $existingUsersCount = User::query()->count();
    $response = $this->postJson('/api/auth/register', [
        'email' => fake()->safeEmail(),
        'name' => fake()->firstName(),
        'password' => 'password',
        'password_confirmation' => 'password',
    ]);
    $this->assertDatabaseCount('users', $existingUsersCount + 1);
    $this->assertDatabaseCount('personal_access_tokens', 1);
    $response->assertCreated();
    $user = User::query()->where('email', $response->json()['user']['email'])->first();

    // $token = $response->json()['token'];
    // $this->getJson('api/user', headers: [
    //     'Authorization' => "Bearer $token"
    // ])->assertOk();

    $this->assertAuthenticatedAs($user, 'sanctum');
}

奇怪的是,取消注释这段带token的请求代码后,assertAuthenticatedAs断言就能通过:

$token = $response->json()['token'];
$this->getJson('api/user', headers: [
        'Authorization' => "Bearer $token"
    ])->assertOk();

注册控制器代码:

public function register(Request $request)
{
    $data = $request->validate([
        'email' => ['required', 'email', 'unique:users,email'],
        'name' => ['required'],
        'password' => ['required', 'confirmed'],
    ]);

    $user = User::query()->create($data)->fresh();

    $token = $user->createToken('email');

    return response()->json([
        'user' => $user,
        'token' => $token->plainTextToken,
    ], HttpStatus::CREATED->value);
}

原因解释

核心逻辑是:assertAuthenticatedAs检查的是当前测试请求上下文的认证状态,而非数据库中是否存在用户的token。

  • 注册接口的作用只是创建用户和对应的token凭证,但测试脚本本身的请求上下文并没有通过这个token完成“登录”流程。assertAuthenticatedAs依赖的是测试进程中Sanctum守卫所持有的已认证用户实例,此时守卫里并没有这个用户。
  • 当你发起带Authorization头的请求时,Sanctum会验证token的有效性,然后在当前测试的上下文里设置认证用户。这时候assertAuthenticatedAs就能检测到守卫中的用户,断言自然通过。

替代方案

如果不想发起额外的API请求,也可以手动让测试上下文的Sanctum守卫认证用户:

$this->actingAs($user, 'sanctum');
$this->assertAuthenticatedAs($user, 'sanctum');

直接调用actingAs方法,指定用户和guard,就能让assertAuthenticatedAs断言通过,无需额外请求。

内容的提问来源于stack exchange,提问作者KWARN KHAM

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 23:03:35