Unit Testing中能否校验目标数组是否符合指定结构及对应字段类型要求
该需求完全可以实现,你可以通过自定义递归校验方法或者直接使用单元测试框架的现成断言完成校验,以下是具体实现方案:
方案1:自定义递归校验函数(通用灵活)
你可以写一个递归函数同时遍历基准结构和待校验数组,依次校验键是否存在、字段类型是否匹配,示例代码如下:
// 递归校验方法,支持返回具体错误信息 function validateArrayStructure(array $benchmark, array $target, string $parentKey = ''): array|bool { foreach ($benchmark as $key => $expectedType) { $currentKey = $parentKey ? $parentKey . '.' . $key : $key; // 校验键是否存在 if (!array_key_exists($key, $target)) { return [ 'error' => "缺少必填字段:{$currentKey}" ]; } // 子结构递归校验 if (is_array($expectedType)) { if (!is_array($target[$key])) { return [ 'error' => "字段 {$currentKey} 类型错误,期望数组,实际为" . gettype($target[$key]) ]; } $subCheck = validateArrayStructure($expectedType, $target[$key], $currentKey); if ($subCheck !== true) { return $subCheck; } continue; } // 类型映射适配PHP gettype返回值 $typeMap = [ 'int' => 'integer', 'float' => 'double', 'bool' => 'boolean', ]; $checkType = $typeMap[$expectedType] ?? $expectedType; $actualType = gettype($target[$key]); if ($actualType !== $checkType) { return [ 'error' => "字段 {$currentKey} 类型错误,期望 {$expectedType},实际为 {$actualType}" ]; } } // 若需要禁止待校验数组出现基准外的额外字段,放开下方注释 // $extraKeys = array_diff_key($target, $benchmark); // if (!empty($extraKeys)) { // $extraKeyStr = implode(', ', array_keys($extraKeys)); // return [ // 'error' => "存在未定义的额外字段:{$parentKey}.{$extraKeyStr}" // ]; // } return true; }
在单元测试中调用方式:
// 你的基准结构 $benchmark = [ 'key' => [ 'key2' => [ 'key3' => 'string', 'key4' => 'int', 'key5' => 'string', 'key6' => 'float', 'key7' => 'string', 'key8' => 'int', 'key9' => [ 'key10' => 'string', 'key11' => 'string', ], 'key12' => [ 'key13' => 'string', ], ] ] ]; // 待校验数组 $target = [/* 你的待校验数据 */]; $checkResult = validateArrayStructure($benchmark, $target); $this->assertTrue($checkResult === true, $checkResult['error'] ?? '数组结构校验失败');
方案2:使用PHPUnit现成断言(适合PHPUnit 9.3+版本)
你可以先把基准结构转换成JSON Schema格式,直接调用PHPUnit的assertMatchesJsonSchema断言完成校验,无需自行实现递归逻辑。
内容的提问来源于stack exchange,提问作者Uxe
相关产品推荐
相关产品推荐

