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
相关产品推荐
相关产品推荐

