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

Laravel assertJson使用has校验根属性时为何失败?

Laravel API测试assertJson闭包断言意外失败

问题场景

API返回的JSON结构:

{
  "data": [
     { 
       "id": 1
     }
  ],
  "meta": {
    "foo": "bar"
  },
  "links": {
    "self": "/"
  }
}

执行的测试代码:

$response
    ->assertOk()
    ->assertJson(fn (AssertableJson $json) =>
        $json
           ->has('data')
    );

测试失败抛出错误:

Unexpected properties were found on the root level.
Failed asserting that two arrays are identical.

 --- Expected
 +++ Actual

 -Array &0 ()
 +Array &0 (
 +    1 => 'links'
 +    2 => 'meta'
 +)

原本预期仅校验data键存在即可,但测试失败;改用$json->hasAll(['data', 'meta', 'links'])后测试成功。

原因解析

Laravel的AssertableJson闭包断言默认启用严格模式:它不仅会检查你声明的键是否存在,还会验证当前校验层级(这里是根级)不存在任何未被显式声明的额外键。所以当响应里有meta和links这两个未在闭包中声明的根级键时,就触发了断言失败。

解决办法

  1. 仅校验指定键,忽略额外键:
    在闭包断言末尾添加->ignore()方法,告诉校验器忽略未被显式声明的额外键:

    $response
        ->assertOk()
        ->assertJson(fn (AssertableJson $json) =>
            $json
               ->has('data')
               ->ignore() // 忽略未声明的其他根级键
        );
    
  2. 校验所有预期存在的键:
    如果你需要确保所有根级键都存在,就使用hasAll方法枚举所有预期的根级键,也就是你测试成功的方式:

    $response
        ->assertOk()
        ->assertJson(fn (AssertableJson $json) =>
            $json
               ->hasAll(['data', 'meta', 'links'])
        );
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 10:45:33