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

如何用PHPUnit测试Laravel8中Passport认证的API端点?

解决Passport保护API端点的测试问题

先处理AppUser工厂的"Unknown format 'name'"错误

这个错误是因为你的AppUser工厂里name字段的Faker调用格式有误,或者字段配置存在问题:

  1. 打开Database\Factories\AppUserFactory.php,检查definition()方法里的name字段:

    • 确保使用正确的Faker方法调用,比如$this->faker->name()(注意括号,Faker的大多数格式是方法形式);如果你的AppUser模型里没有name字段,直接移除该字段的工厂配置即可。
    • 正确的工厂示例:
      namespace Database\Factories;
      
      use App\Models\AppUser;
      use Illuminate\Database\Eloquent\Factories\Factory;
      use Illuminate\Support\Str;
      
      class AppUserFactory extends Factory
      {
          protected $model = AppUser::class;
      
          public function definition()
          {
              return [
                  'name' => $this->faker->name(),
                  'email' => $this->faker->unique()->safeEmail(),
                  'email_verified_at' => now(),
                  'password' => bcrypt('password'),
                  'remember_token' => Str::random(10),
              ];
          }
      }
      
  2. 确保AppUser模型符合Passport要求:
    你的AppUser必须继承Illuminate\Foundation\Auth\User(该类已实现Authenticatable契约),并引入Passport的HasApiTokens trait:

    namespace App\Models;
    
    use Illuminate\Foundation\Auth\User as Authenticatable;
    use Illuminate\Notifications\Notifiable;
    use Laravel\Passport\HasApiTokens;
    use Illuminate\Database\Eloquent\Factories\HasFactory;
    
    class AppUser extends Authenticatable
    {
        use HasApiTokens, Notifiable, HasFactory;
    
        // 配置可填充字段、隐藏字段等
        protected $fillable = ['name', 'email', 'password'];
        protected $hidden = ['password', 'remember_token'];
    }
    

正确测试受保护的/post端点

方法1:用actingAs指定API guard

修复工厂和模型后,测试时需要给actingAs方法指定api guard(Passport默认使用api guard):

public function testPostEndpoint()
{
    // 创建认证用户
    $user = AppUser::factory()->create();

    // 指定api guard进行认证
    $this->actingAs($user, 'api');

    // 发送请求到/post端点(根据你的端点类型用get/post等)
    $response = $this->get('/post');

    // 断言请求成功
    $response->assertStatus(200);
}

方法2:模拟真实客户端流程(通过register获取token)

如果想更贴近真实使用场景,可以先调用register端点获取Bearer Token,再用该Token请求/post:

public function testPostEndpointWithRegisteredToken()
{
    // 调用register端点注册用户
    $registerResponse = $this->post('/register', [
        'name' => '测试用户',
        'email' => 'test@example.com',
        'password' => 'password',
        'password_confirmation' => 'password',
    ]);

    // 提取返回的access_token
    $token = $registerResponse->json('access_token');

    // 携带Token请求/post端点
    $response = $this->withHeaders([
        'Authorization' => "Bearer {$token}",
    ])->get('/post');

    $response->assertStatus(200);
}

关于默认User模型的类型错误

你用默认User模型时出现的类型错误,大概率是因为User模型没有继承Illuminate\Foundation\Auth\User(未实现Authenticatable契约),或者测试时没指定api guard。但既然你使用的是自定义AppUser,优先修复AppUser的配置即可。

内容的提问来源于stack exchange,提问作者Siddhartha Choubey

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 17:47:03