如何用PHPUnit测试Laravel8中Passport认证的API端点?
解决Passport保护API端点的测试问题
先处理AppUser工厂的"Unknown format 'name'"错误
这个错误是因为你的AppUser工厂里name字段的Faker调用格式有误,或者字段配置存在问题:
打开
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), ]; } }
- 确保使用正确的Faker方法调用,比如
确保AppUser模型符合Passport要求:
你的AppUser必须继承Illuminate\Foundation\Auth\User(该类已实现Authenticatable契约),并引入Passport的HasApiTokenstrait: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
相关产品推荐
相关产品推荐

