Flutter单元测试中如何校验Map数组并实现指定JSON返回逻辑
Flutter单元测试中Map数组空态测试数据统一生成实现
核心逻辑
针对单元测试中需要快速构造边界空态JSON/Map参数的需求,通过递归遍历的方式处理任意层级的Map、List(含Map数组)结构,保留原数据层级关系的同时,自动为所有叶子字段赋值null或空字符串,无需逐字段手动构造测试用例。
支持两种常用空态模式:
- 全字段强制返回
null - 字符串类型字段返回空字符串
'',其余类型字段返回null
自动兼容嵌套Map、数组嵌套Map、基础类型数组等常见JSON结构,处理过程不会修改原始入参对象,避免测试用例之间的数据污染。
实现代码
// 空值生成模式枚举 enum EmptyTestType { forceNull, // 所有叶子字段返回null emptyStringForString, // 字符串类型叶子字段返回空字符串,其余返回null } /// 统一空态测试数据生成函数 /// [originalPayload] 原始正常结构的业务参数,支持Map、List、基础类型任意入参 /// [emptyType] 空值生成模式,默认为全字段返回null dynamic generateEmptyTestPayload( dynamic originalPayload, { EmptyTestType emptyType = EmptyTestType.forceNull, }) { // 处理Map结构节点 if (originalPayload is Map<String, dynamic>) { final Map<String, dynamic> processedMap = {}; originalPayload.forEach((key, value) { // 嵌套结构递归处理 if (value is Map || value is List) { processedMap[key] = generateEmptyTestPayload(value, emptyType: emptyType); } else { // 叶子节点按规则赋值空态 if (emptyType == EmptyTestType.emptyStringForString && value is String) { processedMap[key] = ''; } else { processedMap[key] = null; } } }); return processedMap; } // 处理List/数组结构节点(覆盖Map数组场景) if (originalPayload is List) { // 保留原数组长度,逐元素递归处理,贴合真实接口返回结构 return originalPayload .map((item) => generateEmptyTestPayload(item, emptyType: emptyType)) .toList(); } // 基础类型叶子节点兜底处理 if (emptyType == EmptyTestType.emptyStringForString && originalPayload is String) { return ''; } return null; }
单元测试使用示例
void main() { test('Map数组入参空态兼容性测试', () { // 原始业务正常入参样例(Map数组类型) final List<Map<String, dynamic>> normalUserListPayload = [ { "userId": 1001, "userName": "zhangsan", "isVip": true, "profile": { "avatar": "avatar_path", "bio": "test intro" }, "tagList": ["flutter", "unit_test"] } ]; // 生成全字段为null的测试数据 final nullFieldPayload = generateEmptyTestPayload(normalUserListPayload); // 生成字符串字段为空、其余字段为null的测试数据 final emptyStringPayload = generateEmptyTestPayload( normalUserListPayload, emptyType: EmptyTestType.emptyStringForString, ); // 直接传入待测试的业务方法/JSON解析方法即可 expect(() => parseUserListFromJson(nullFieldPayload), returnsNormally); expect(() => parseUserListFromJson(emptyStringPayload), returnsNormally); }); }
扩展说明
- 如果需要测试数组本身为空的场景,直接传入
[]作为原始入参即可,该函数主要解决字段级空态的自动生成问题 - 若业务需要其他类型的默认空值(比如数字类型返回0、布尔类型返回false),直接在叶子节点的判断分支中扩展对应类型的返回规则即可
- 函数返回的是全新生成的数据实例,和原始入参完全隔离,不会修改原始测试数据影响其他用例执行
内容的提问来源于stack exchange,提问作者cadeting
相关产品推荐
相关产品推荐

