Laravel测试已登录用户登出时出现500错误问题排查
Laravel Sanctum登出测试返回500错误:尝试在null上调用delete()方法
测试用户登出功能时遇到问题,已卡壳一天未找到解决方案。调用route('api.logout')返回500错误,提示尝试在null上调用delete()方法。
原测试文件代码
namespace Tests\Feature; use App\Models\User; use Illuminate\Database\Eloquent\Factory; use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Foundation\Testing\WithoutMiddleware; use Symfony\Component\HttpFoundation\Response; use Tests\TestCase; class AuthControllerTest extends TestCase { use RefreshDatabase, WithoutMiddleware; private array $userData; public function setUp(): void { parent::setUp(); $this->userData = [ 'email' => 'admin@mydomain.com', 'password' => '12345633', 'password_confirmation' => '12345633', 'name' => 'admin', 'remember_me' => true ]; } public function test_can_register_a_user(): void { $response = $this->post(route('api.register'), $this->userData); $response->assertStatus(Response::HTTP_OK); $content = $response->json(); $this->assertNotNull($content['id']); } public function test_can_login_a_user(): void { $this->test_can_register_a_user(); $response = $this->post(route('api.login', $this->userData)); $response->assertStatus(Response::HTTP_OK); $content = $response->json(); $this->assertNotNull($content['id']); } public function test_can_logout_a_user(): void { $this->test_can_login_a_user(); $user = User::where('email', '=', $this->userData['email'])->first(); $this->actingAs($user); $response = $this->delete(route('api.logout')); $response->assertStatus(Response::HTTP_OK); } }
原控制器登出函数
public function logout(Request $request) { $user = auth()->user(); $user->currentAccessToken()->delete(); }
已尝试的无效方案
- 在
test_can_logout_a_user方法中添加Session::start() - 使用
$this->be替代actingAs
用户实例存在,但无任何令牌,调用$user->tokens()返回0个令牌。
环境信息
- 使用SQLite内存数据库
- 在POSTMAN或INSOMNIA中登出功能正常,但测试时失败
- 采用Laravel Sanctum做认证,怀疑是Laravel 9与Sanctum的兼容问题
更新后的测试代码
public function test_can_logout_a_user(): void { $user = User::create($this->userData); $token = $user->createToken('Test token')->plainTextToken; $response = $this->json('DELETE', route('api.auth.logout'), [], ['Authorization' => "Bearer $token"]); $response->assertStatus(Response::HTTP_OK); }
更新后的控制器登出函数
use Laravel\Sanctum\PersonalAccessToken; // ... public function logout(Request $request) { $accessToken = $request->bearerToken(); $token = PersonalAccessToken::findToken($accessToken); $token->delete(); }
内容的提问来源于stack exchange,提问作者Rafael Benito Pérez González
相关产品推荐
相关产品推荐

