
本文介绍如何在 Laravel 测试中准确验证嵌套 JSON 数组(如 items.*.id)中所有 ID 是否匹配预期值,解决 where() 不支持通配符数组断言的限制,并提供可排序无关、健壮可靠的断言方案。
本文介绍如何在 laravel 测试中准确验证嵌套 json 数组(如 `items.*.id`)中所有 id 是否匹配预期值,解决 `where()` 不支持通配符数组断言的限制,并提供可排序无关、健壮可靠的断言方案。
在 Laravel 的 HTTP 测试中,assertJson() 配合 AssertableJson 提供了强大的 JSON 结构校验能力,但其链式断言方法(如 where()、whereAll())*不支持对动态索引数组字段(如 `items..id)直接进行批量值比对**——例如->where('items.*.id', [10, 20])` 会失败,因为通配符路径无法映射到一维值数组。
正确的做法是结合 AssertableJson::toArray() 提取原始数据,再用 PHP 原生逻辑完成灵活校验。以下为推荐实现:
$this->getJson(route('report.view'))
->assertStatus(200)
->assertJsonIsObject()
->assertJson(function (AssertableJson $json) {
$expectedIds = [10, 20];
$json->has('items', count($expectedIds)) // 先断言 items 数量准确
->has('items', function (AssertableJson $items) use ($expectedIds) {
// 将 items 数组转为 PHP 数组,提取所有 id 值
$actualIds = array_column($items->toArray(), 'id');
// 验证每个期望 ID 都存在于响应中(顺序无关)
foreach ($expectedIds as $id) {
$this->assertContains($id, $actualIds);
}
// 【可选】进一步确保无多余 ID(严格双向校验)
$this->assertCount(count($expectedIds), $actualIds);
$this->assertEqualsCanonicalizing($expectedIds, $actualIds);
});
});✅ 关键要点说明:
将一个或多个视频上传至YouTube。当用户想“上传到YouTube”“发YouTube”“批量上传”“upload to YouTube”“post videos to YouTube”或发布到YouTube时使用此技能。
-
has('items', $count)确保数组长度一致,避免漏项或冗余; -
array_column(..., 'id')安全提取所有id字段值(即使结构稍有变化也健壮); - 使用
assertContains()实现“存在性断言”,天然兼容任意顺序; - 追加
assertEqualsCanonicalizing()可实现完全等价校验(内容相同、顺序无关),比单纯assertContains更严格; - 避免依赖
where()的路径通配符幻想——Laravel 当前版本(≤11.x)尚未支持该语法,强行使用将导致断言静默失败或抛出异常。
? 进阶提示: 若需复用该逻辑,可封装为测试 Trait 方法:
protected function assertJsonIds(AssertableJson $json, string $path, array $expected): void
{
$json->has($path, count($expected))
->has($path, function (AssertableJson $collection) use ($expected) {
$actual = array_column($collection->toArray(), 'id');
$this->assertEqualsCanonicalizing($expected, $actual);
});
}然后在测试中简洁调用:$json->assertJsonIds('items', [10, 20]);
此方案稳定、清晰、可维护,是 Laravel 官方推荐模式的合理延伸。

















