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

Laravel中使用PHPUnit测试传递给视图的数据是否含指定键的实现方法

方案1:直接复用Laravel内置Arr::has快速校验

Laravel 提供的Illuminate\Support\Arr辅助类的has方法原生支持多维数组嵌套键校验,直接传入待校验的键列表即可:

use Illuminate\Support\Arr;

// 拿到视图数据后转成数组
$viewData = (array) $this->get(route('news.show',['slug' => $post->slug]))
                   ->assertOk()
                   ->getOriginalContent()
                   ->getData();

// 校验指定键是否全部存在,支持点语法写嵌套键
$this->assertTrue(Arr::has($viewData, [
    'post',
    'post.id',
    'post.main_title',
    'post.secondary_title',
    'post.user.name',
    'post.image.path',
    'permissions',
    'permissions.access_to_edit',
    'permissions.access_to_delete'
]));
方案2:自定义递归断言,实现你想要的assertArrayStruct用法

在你的项目测试基类TestCase.php中添加自定义断言方法,后续所有测试都可以直接调用:

// 追加到 tests/TestCase.php 中
protected function assertArrayStructure(array $expectedStructure, array $actualArray): void
{
    foreach ($expectedStructure as $key => $child) {
        if (is_array($child)) {
            // 嵌套结构,先校验父键存在,再递归校验子结构
            $this->assertArrayHasKey($key, $actualArray);
            $this->assertArrayStructure($child, $actualArray[$key]);
        } else {
            // 普通键,直接校验存在
            $this->assertArrayHasKey($child, $actualArray);
        }
    }
}

调用方式完全符合你预期的写法:

$viewData = (array) $response->getOriginalContent()->getData();

$this->assertArrayStructure([
    'post' => [
        'id',
        'main_title',
        'secondary_title',
        'user' => ['name'],
        'image' => ['path']
    ],
    'permissions' => [
        'access_to_edit',
        'access_to_delete'
    ]
], $viewData);
方案3:复用现有assertJsonStructure无需额外编码

把视图数据转成JSON格式,直接复用Laravel已经提供的assertJsonStructure方法,不用自己封装逻辑:

$viewData = $this->get(route('news.show',['slug' => $post->slug]))
                   ->assertOk()
                   ->viewData();

$this->assertJsonStructure([
    'post' => [
        'id',
        'main_title',
        'secondary_title',
        'user' => ['name'],
        'image' => ['path']
    ],
    'permissions' => ['access_to_edit', 'access_to_delete']
], json_encode($viewData));
补充:如果需要同时校验键值匹配

不需要逐行写assertEquals,用模型的only方法批量提取指定字段对比即可:

$expectedPost = $post->load('user', 'image');
$actualPost = $viewData['post'];

$this->assertEquals(
    $expectedPost->only('id', 'main_title', 'secondary_title', 'context', 'slug', 'comment', 'like', 'dislike', 'view', 'created_at'),
    $actualPost->only('id', 'main_title', 'secondary_title', 'context', 'slug', 'comment', 'like', 'dislike', 'view', 'created_at')
);
$this->assertEquals($expectedPost->user->name, $actualPost['user']['name']);
$this->assertEquals($expectedPost->image->path, $actualPost['image']['path']);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.16 09:15:03