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这两个未在闭包中声明的根级键时,就触发了断言失败。
解决办法
仅校验指定键,忽略额外键:
在闭包断言末尾添加->ignore()方法,告诉校验器忽略未被显式声明的额外键:$response ->assertOk() ->assertJson(fn (AssertableJson $json) => $json ->has('data') ->ignore() // 忽略未声明的其他根级键 );校验所有预期存在的键:
如果你需要确保所有根级键都存在,就使用hasAll方法枚举所有预期的根级键,也就是你测试成功的方式:$response ->assertOk() ->assertJson(fn (AssertableJson $json) => $json ->hasAll(['data', 'meta', 'links']) );
内容的提问来源于stack exchange,提问作者pascalvgemert
相关产品推荐
相关产品推荐

