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

如何在Laravel/Lumen控制器构造函数获取登录用户ID时通过API测试?

问题分析

你遇到的错误根源是:测试中调用withoutMiddleware()禁用了认证中间件,导致$request->user()返回null,控制器构造函数里访问$request->user()->userId会触发致命错误,最终接口返回的不是预期的JSON结构,seeJsonStructure断言时因找不到对应数组结构抛出assertArrayHasKey参数错误。

解决方案

方案1:模拟用户登录(推荐)

不要禁用认证中间件,而是在测试中创建并模拟登录用户,让请求携带合法的用户实例:

public function testShowOneItemReturnsOnePayroll() {
    // 创建测试用户(需确保User模型工厂已配置)
    $user = factory(App\User::class)->create(['userId' => 1001]);
    // 模拟用户登录
    $this->actingAs($user);
    
    $this->json('GET', "intranet");
    $this->seeJsonStructure([
      'data' => [
        'prId',
        'userId',
        'firstName',
        'lastName',
        ...
      ]
    ]);
}

这种方式贴近真实业务场景,同时保证控制器能正常获取loggedInUserId。

方案2:给控制器添加空值安全处理

如果业务允许无用户访问的场景,可以修改构造函数避免空指针错误:

private $loggedInUserId;

public function __construct(Request $request) {
    // 使用null安全运算符,避免$request->user()为null时报错
    $this->loggedInUserId = $request->user()?->userId;
}

注意:需要确保控制器后续逻辑能处理loggedInUserId为null的情况。

方案3:手动给请求绑定用户(不推荐)

如果坚持要禁用中间件,可以手动为请求注入用户实例:

public function testShowOneItemReturnsOnePayroll() {
    $user = factory(App\User::class)->create(['userId' => 1001]);
    
    // 创建请求并设置用户解析器
    $request = Request::create("intranet", 'GET');
    $request->setUserResolver(fn() => $user);
    
    // 将请求绑定到容器
    $this->app->instance('request', $request);
    
    $this->json('GET', "intranet");
    $this->seeJsonStructure([
      'data' => [
        'prId',
        'userId',
        'firstName',
        'lastName',
        ...
      ]
    ]);
}

此方法操作繁琐,仅适用于特殊测试场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 10:45:34