我是在一个支付系统重构项目里,第一次对“Mock数据的真实性”这件事产生强烈不信任感的。
当时我们的任务是给结算引擎写单元测试。接口文档里有一个批量打款接口,请求参数包含收款人姓名、银行卡号、金额、分行号等。我让团队里一位工程师用 Claude Code 辅助生成 Mock 数据。他给了一个很简短的 prompt,得到了一批看起来很规范的数据:姓名是“张三”、“李四”,卡号是19位数字,金额是100的整数倍,分行号是标准的12位联行号格式。
测试跑通了,覆盖率也很漂亮。直到有一天,我随手从中抽了一条数据做人工审查,发现一个致命问题:卡号和分行号完全不匹配。卡号归属地是上海,分行号却是广东某偏远支行的。更严重的是,有一笔金额是100.00,但根据业务规则,低于500元的打款不应该进这个接口,因为它只处理大额批量支付。
这些 Mock 数据“格式真”,但“业务假”。如果带着这样的数据上线,我们可能在测试环境里自我欺骗几个月,然后在上线第一周收到银行退票通知。
这件事直接促使我开始系统研究:Claude Code 生成 Mock 数据时,所谓的“真实性”到底是什么? 以及更重要的,我们如何在工程实践中获得真正可信、可用于高风险场景的测试数据?
这篇文章是我在过去半年里,经过三个项目迭代、十几个接口的实践后,形成的完整思考和操作框架。
一、先给一个绕不开的核心结论
在深入具体案例和方法论之前,我想先把结论放在最前面,因为这对后续所有讨论都至关重要。
Claude Code 能够生成在格式、类型、字段范围上高度符合 Schema 要求的 Mock 数据,但它不具备对隐含业务逻辑的主动理解能力。Mock 数据的“真实性”不是 AI 自动赋予的属性,而是由开发者通过输入上下文、约束条件和校验流程共同构建出来的。
换句话说,Claude Code 是一面镜子,它反射的是你注入的规则质量,而不是凭空产生了“真实”。
这个结论来自大量的实验与比对。我曾在同一个接口上,用三种不同粒度的 Prompt 让 Claude Code 生成 Mock 数据:
- 粗糙 Prompt:“帮我生成10条用户订单 Mock 数据”。结果:类型正确,但订单金额和商品单价不一致,支付时间早于订单创建时间,用户ID全是10001。
- 中等 Prompt:“生成订单数据,订单总金额必须等于商品单价乘以数量,支付时间不能早于创建时间”。结果:逻辑关系正确了,但金额都是整数,商品名都是“Item A”,没有覆盖优惠券、部分退款等场景。
- 精确 Prompt:提供了完整业务规则文档、真实脱敏数据样例、边界值要求。结果:数据在多个维度上都接近生产环境分布。
差异巨大。这意味着“真实性”的掌控权完全在开发者手里,而不是在模型那里。接受这个前提,我们才能讨论后面的技术细节。

二、回到真实场景:我们到底为什么要追求 Mock 数据的真实性
很多技术文章在讨论 Mock 数据时,会直接跳到“如何生成”这一步,却很少花时间讲清楚一个前置问题:单元测试里的 Mock 数据,够用不就行了吗?为什么要逼真?
这问题背后其实藏着两种完全不同的测试哲学。
第一种是我称之为“隔离主义”的思路。它主张单元测试只测试代码逻辑,Mock 对象只是依赖的替身,只要返回值能让代码路径走通就行。比如,被测方法里有一个 if amount > 1000 的分支,那 Mock 数据给一个 1001 和 999 就够了。这种思路下,Mock 数据完全不需要“真实”,它只需要“够用”。
第二种是“行为验证”的思路。它认为单元测试不仅要验证代码路径,更要验证代码在接近真实数据环境下的行为是否正确。比如上面提到的打款接口,如果你只测试了 amount = 1001 的场景,你永远不会发现当金额为零、负数、或者超过单日限额时,代码是直接崩掉还是优雅返回错误码。
我在过去的实践中犯过一个严重的错误:就是太相信第一种思路。当时我们有一个风控规则引擎,对交易金额和频次做了复杂的阈值判断。单元测试用的 Mock 数据全是“恰好符合条件”或者“恰好不符合条件”的干净数据。结果上线后,风控引擎在灰度期间误拦率飙升到 23%,原因很荒谬:真实交易数据里有大量的小数点后三位、负数冲正、时间戳毫秒级偏差,这些在我们的测试里一条都没出现过。
这次事故之后,我在团队里定了一条原则:单元测试的 Mock 数据,必须模拟生产环境的复杂性和肮脏度。 这并不是说要把生产数据搬下来(那是违规的),而是说在数据特征层面,要让人工生成的 Mock 能逼近真实分布。
Claude Code 在这个原则下,才真正体现了它的价值。传统手写 Mock 数据时,要模拟这种复杂性和肮脏度,意味着你得手动构造几十甚至上百条数据,覆盖各种异常、边界、组合场景,太慢了。Claude Code 的优势在于,只要你描述清楚“复杂”的定义,它能瞬间生成海量符合复杂规则的数据。但前提仍然是:你得描述清楚。

三、拆解三个常见误区:你以为的“真实”,可能根本不是真实
这半年我看了很多团队使用 AI 写测试的方法,也和同行交流过,发现对“Mock 数据真实性”的理解,有三个非常典型的误区。
误区一:格式正确等于真实
这是我最早踩的坑,也是大多数人最容易掉的坑。
一个 JSON 对象的字段类型、长度、格式符合 Schema 定义,不等于这个数据是真实的。举个简单例子:一个用户注册接口的 Mock 数据里,name 是“王小明”,age 是 25,idNumber 是 18 位数字,格式全对。但如果你仔细看,这个身份证号的校验码是错的,出生日期和年龄对不上(身份证显示 1995 年出生,但 age 写的是 25,而当前是 2025 年,实际应为 30 岁)。更隐蔽的是,这个身份证号里的地区码不存在。
这类错误在手工 Mock 里也很常见,但 Claude Code 如果没有被显式告知“身份证号需要符合校验规则,年龄需要与出生日期匹配”,它就会堂而皇之地生成格式正确但逻辑矛盾的数据。
真实性的第一个层次,是字段间的逻辑自洽。
误区二:用 Faker 之类的库就能解决真实性问题
很多开发者认为,引入 Faker、Chance.js 这样的 Mock 工具库,就能生成真实的数据。Faker 能生成看起来像真人的姓名、地址、电话,这没错。但它有两个致命缺陷:
- 无法实现跨字段的关联约束。faker.name.firstName() 和 faker.date.birthday() 是完全独立的,你没法保证生成的姓名性别和身份证号性别标识一致。
- 无法模拟业务流程导致的数据状态分布。比如,一个订单系统里,退款状态的订单占比应该在 5% 左右,收货后超期未评价的订单占比应该在 8%,这些都是业务规则决定的。Faker 没有业务上下文,它只能产生均匀分布或者简单加权分布的随机数据。
而 Claude Code 的价值恰恰在于:它可以理解自然语言描述的业务规则,并据此生成具有特定分布特征的关联数据。 这是它在 Mock 数据真实性维度上,超越传统随机库的核心能力。
误区三:AI 生成的数据可以用更多 AI 来验证
有一个颇具迷惑性的观点:AI 生成的 Mock 数据,再让另一个 AI 去校验它的真实性,形成闭环。听起来很完美,但我实测过,这几乎不可行。
我曾尝试让 Claude Code 生成一批 Mock 数据,然后用另一个大模型去审查数据中的逻辑漏洞。结果令人失望:第二个模型对很多错误视而不见,反而对一些正确但罕见的数据提出了错误质疑。根本原因在于,当前的大模型不具备对特定业务系统的正向验证能力,它没有数据库去核对你的卡号是否匹配分行号,没有你的业务规则文档去判断这笔订单的优惠券叠加是否合理。
因此,最终的校验必须由开发者完成,而且必须依赖可执行的规则引擎和 Schema 校验器,而非另一个 AI。

四、一个四维评估框架:如何判断你的 Mock 数据有多“真”
既然“真实性”不是非黑即白的二元判断,我们就需要一个可操作、可衡量的评估框架。根据这六个多月在几个业务系统上的反复试验,我提炼出了一个四维模型,用来给 Mock 数据的真实性打分。
维度一:结构真实性
这是最基础的维度。结构真实性衡量 Mock 数据是否符合接口定义的格式和类型要求。
- 评级方式:是否通过 JSON Schema / OpenAPI 规范的自动校验。
- 典型问题:字段缺失、类型错误(string 写了数字)、数组长度不符合 minItems/maxItems 约束。
- Claude Code 在这一维度的表现:极强。只要你在 Prompt 里提供了 Schema 定义,Claude Code 几乎不会在这里犯错。即使你不提供 Schema,只描述字段,它也极少出现类型错误。
这个维度 AI 已经高度可靠,不需要花费精力验证。
维度二:逻辑一致性
这是最容易出问题、也是开发者最容易忽视的维度。它衡量数据内部是否存在自相矛盾的逻辑。
我们用一个真实例子来说明。假设有一个保险投保接口,Mock 数据包含:投保人年龄、保险类型、保额、保费。逻辑一致性要求:
- 年龄必须与生日匹配。
- 保险类型决定了保额上限(比如重疾险最高 50 万,寿险最高 200 万)。
- 保费必须根据年龄、保额、险种按照费率表计算得出。
在一次测试中,我让 Claude Code 生成了 100 条这样的 Mock 数据。不检查不知道,一检查发现:有 12 条数据的年龄小于 18 岁却买了寿险(未成年人不可投保),8 条保额超过了该险种上限,而保费全部是随机数字,没有一条是按费率表算的。
问题的根源在于,我给的 Prompt 里只描述了字段名称和类型,没有描述这些规则。Claude Code 的知识库里可能有一些保险常识,但它不可能知道我们公司的具体费率表。
提升逻辑一致性的方法:
- 在 Prompt 中显式列出字段间的依赖规则。
- 提供计算公式(如
premium = amount * rate[age] * duration)。 - 用“当…时,…必须…”的句式约束条件分支。
维度三:分布真实性
这是把 Mock 数据从“看起来对”推向“用起来对”的关键维度。它要求 Mock 数据集在统计分布上接近真实生产数据的特征。
举个例子,我们系统里有一个商品推荐接口,返回的商品列表需要符合用户的兴趣标签。真实的线上数据中,用户点击推荐商品的比例大约在 12%,其中 80% 的点击集中在头部 20% 的商品上(幂律分布)。但如果你用均匀分布来生成 Mock 数据,所有商品被点击的概率一样,那你永远测试不出推荐算法的排序效果。
分布真实性的核心指标包括:
| 分布特征 | 描述 | 失真后果 | Claude Code 控制方式 |
|---|---|---|---|
| 字段值分布 | 枚举字段各值占比、数值字段的概率分布 | 测试缺失对长尾场景的覆盖 | 在 Prompt 中指定比例,如“status 中 pending 占 60%,paid 占 30%,refunded 占 10%” |
| 时间序列模式 | 数据的时间戳是否呈现周期性、趋势性 | 时序相关逻辑(如对账、超时)无法被验证 | 提供时间分布描述,如“created_at 集中在工作日的 9:00-18:00,周末无数据” |
| 关联强度 | 多维字段间的关联是否反映真实关系 | 无法验证聚类、推荐、评分模型 | 提供业务场景约束,如“用户A的订单通常属于类目X,偶尔出现类目Y” |
| 异常值比例 | 是否存在空值、极值、格式错误 | 鲁棒性测试缺失 | 明确要求“5%的amount字段为null,2%的phone字段格式错误” |

维度四:行为仿真性
这是最高阶的真实性维度,也是大多数人完全忽略的。行为仿真性要求 Mock 数据不仅仅是静态快照,而是能够驱动被测代码走过完整的业务流程链。
单元测试通常只测一个方法或一个类,但真实系统是链式调用的。一个订单数据从创建到完成,会经过多个状态的流转,每个状态都伴随不同的事件和副作用。如果你只 mock 了最终状态的订单对象,你跳过了中间所有状态的迁移逻辑测试。
举个例子:我们有一个订单取消逻辑,要求“已支付但未发货的订单”可以全额退款,“已发货”的订单需要扣除运费。写单元测试时,如果你只 mock 了两个不同状态的订单对象(一个已支付未发货,一个已发货),测试都能通过。但上线后我们发现,“正在拣货中”的状态漏掉了,代码对这个状态没有处理,导致异常。
行为仿真性的核心,是生成一个包含状态序列的 Mock 数据集,而不是单一对象。 例如:
// 不好的Mock:只提供一个静态对象
{
"orderId": "10001",
"status": "shipped"
}
// 好的Mock:提供状态流转轨迹
{
"orderId": "10001",
"timeline": [
{"status": "pending", "timestamp": "2025-06-28T09:00:00"},
{"status": "paid", "timestamp": "2025-06-28T09:05:00"},
{"status": "picking", "timestamp": "2025-06-28T09:15:00"},
{"status": "shipped", "timestamp": "2025-06-28T10:30:00"}
]
}
Claude Code 完全可以生成这种带有状态序列的数据,只需要你在 Prompt 中描述状态机的规则。例如:“所有订单从 pending 开始,按照 paid -> picking -> shipped 或 paid -> cancelled 的状态机流转,请为每个订单生成完整的时间线和状态变迁记录,并确保时间戳符合先后顺序。”
五、一个完整案例:订单服务 Mock 数据生成的全过程复盘
为了让你更具体地理解这个框架如何落地,我拆解一个真实的项目案例:重构订单查询服务时的 Mock 数据生成过程。
业务背景
订单查询接口 /orders/query 接收查询参数(用户ID、订单状态、时间范围、分页信息),返回符合条件的订单列表。该服务内部调用了四个下游依赖:
- 订单主表服务(提供订单基础信息)
- 商品服务(提供商品详情)
- 用户服务(提供用户基本信息和会员等级)
- 物流服务(提供物流状态)
我们要为这个查询接口的聚合逻辑编写单元测试,需要 Mock 这四个依赖的返回值。数据真实性的要求非常高,因为查询逻辑里有复杂的过滤、排序、数据拼接和异常处理。
阶段一:基础结构生成(维度一)
第一步很简单,我们提供了每个依赖接口的 JSON Schema 给 Claude Code,指令是:“根据 Schema 生成 50 条 Mock 订单数据,订单状态枚举值随机分布。”
Claude Code 生成了完全符合 Schema 的数据,字段完整,类型正确。但此时的数据有严重问题:
- 50 个订单的
userId全部是 10001,完全没有差异性。 - 商品 ID 列表都是
["prod_001", "prod_002"],所有订单买的都是同样的东西。 created_at全部在同一天。
这时的数据只在结构真实性维度上合格,其他维度全都不及格。
阶段二:注入业务规则(维度二)
接下来,我们向 Claude Code 提供了详细的业务约束文档片段。
我们这样描述约束:
- userId 应该分布在 10001~10050 之间。
- 商品 ID 从商品列表中均匀选取,每个订单包含 1~5 个商品。
- total_amount 必须等于所有商品单价×数量的总和加上运费(运费规则:满 99 包邮,否则 8 元)。
- created_at 和 updated_at 的时间关系必须合理(创建时间不晚于更新时间)。
- 订单状态为“已完成”的,必须有完整的物流信息;状态为“待支付”的,不应有物流信息。
- 会员等级为“黄金”及以上的用户,享受 95 折,体现在 total_amount 中。
Claude Code 重新生成后,数据质量大幅提升。我们随机抽取了 20 条数据进行人工核验:
- 金额计算准确率:18/20 正确(2 条错误是因为优惠券叠加未考虑)。
- 时间逻辑合理率:20/20 正确。
- 物流状态与订单状态匹配率:19/20 正确。
逻辑一致性从最初的几乎为零,上升到了约 90%。

阶段三:模拟真实分布(维度三)
逻辑一致性解决后,数据看起来已经“真”了不少。但当我们把它放到查询性能测试中时,发现了新问题:所有的订单状态都是均匀分布的,pending、paid、completed、cancelled 大约各占 25%。
但真实的生产环境里,cancelled 订单接近 30%,completed 占 50%,pending 只有 5%。这导致测试中某些查询路径(如查询 cancelled 订单)的执行频率远低于线上,而 pending 状态的查询压力被不成比例地放大了。
于是我们进一步细化 Prompt:
“请根据以下分布生成订单状态:cancelled 30%,completed 50%,shipped 10%,paid 5%,pending 5%。同时,80% 的订单创建时间在过去 7 天内,15% 在过去 30 天内,5% 超过 30 天(用于测试归档逻辑)。订单金额服从对数正态分布,中位数约为 150 元,最小值 10 元,最大值 5000 元。”
Claude Code 很聪明地理解了“对数正态分布”这种统计描述,生成的数据直方图与我们预测的曲线高度吻合。
但这里有一个细节值得强调:Claude Code 对统计分布的理解是基于其训练数据中的数学知识,而不是因为它在服务器里运行了统计程序。 这意味着,它可能在生成过程中出现偏差,尤其是在极端分位数上。因此,对于分布要求极高的场景(如金融风控、医疗数据),建议用专门的统计库生成数值,再用 Claude Code 整合到完整数据结构中。
阶段四:构造行为序列(维度四)
最后一步,我们让 Claude Code 为每个订单生成生命周期事件列表。Prompt 大致这样:
“为每个订单生成一个事件列表。每个事件包含:事件类型(created, paid, shipped, delivered, cancelled, refunded)、时间戳、操作人ID。事件必须符合状态机:只有待支付订单可以取消;只有已发货订单可以确认收货。时间戳必须是 ISO 8601 格式,毫秒级,且事件间的间隔合理(支付通常在创建后 0~30 分钟内,发货在支付后 1~24 小时内)。”
生成的结果中,我们得到了类似这样的数据:
{
"orderId": "ORD-20250628-1234",
"events": [
{"type": "created", "timestamp": "2025-06-28T14:23:01.234Z", "operator": "user_10023"},
{"type": "paid", "timestamp": "2025-06-28T14:35:44.567Z", "operator": "payment_gateway"},
{"type": "shipped", "timestamp": "2025-06-29T09:12:33.890Z", "operator": "warehouse_05"},
{"type": "delivered", "timestamp": "2025-06-30T16:45:12.123Z", "operator": "logistics_sys"}
]
}
借助这些事件序列,我们可以为订单状态机写测试,模拟任意时间点下的订单数据重建(Event Sourcing 模式),从而大幅提升了状态迁移逻辑的测试覆盖度。
这个案例的核心经验是:Mock 数据的真实性不是一次生成的静态结果,而是一个逐步注入约束、迭代优化的过程。Claude Code 是这个过程的加速器,但方向盘始终在开发者手里。
六、行动建议:一套可复用的 Prompt 工程与校验流程
结合以上案例和经验,我总结出一套具体的操作流程,分三个阶段:Prompt 编写、数据生成、自动验证。
第一阶段:Prompt 编写,用“规则文档”代替“随口一说”
(1)以接口文档为基础,构建 Prompt 上下文
不要只在 Prompt 里写一句“生成 Mock 数据”,而应该把完整的接口定义、字段说明、业务规则摘要作为上下文提供给 Claude Code。我通常的做法是:
- 从 API 文档平台(如 YApi、Swagger)导出接口定义。
- 粘贴到 Prompt 中作为数据格式约束。
- 额外编写一段“业务规则补充”,包含:
- 字段约束:哪些字段必填,哪些可选、默认值是什么。
- 逻辑关系:字段间的计算关系、互斥关系、依赖关系。
- 枚举说明:每个状态值的含义,以及它们之间的流转逻辑。
- 异常场景:需要构造哪些异常数据(如超长字符串、负数、SQL 注入尝试等)。
(2)使用“约束分层法”组织 Prompt
我设计了一个三层 Prompt 结构,在实践中效果很好:
- 第一层:数据模板层。给出一个或多个数据样例,作为格式参考。
- 第二层:规则描述层。用 if-then 句式描述条件约束。
- 第三层:分布要求层。明确各字段的统计分布和边界值覆盖率。
示例 Prompt 框架:
【数据模板】
请按照以下 JSON 结构生成订单列表:
{
"orders": [
{
"orderId": "string",
"userId": "string",
"items": [
{"productId": "string", "quantity": "number", "unitPrice": "number"}
],
"totalAmount": "number",
"status": "enum",
"createdAt": "ISO8601",
"paidAt": "ISO8601"
}
]
}
【规则描述】
orderId 格式为 ORD-YYYYMMDD-XXXX
totalAmount 必须等于所有 items 的 quantity * unitPrice 之和,并加上运费(满99免运费,否则8元)
status 为 cancelled 时,不应有 paidAt 字段
createdAt 必须早于 paidAt(如果存在)
【分布要求】
订单状态分布:completed 50%, cancelled 30%, paid 15%, pending 5%
userId 在 USR-00001 至 USR-00050 之间随机选取
item 数量 1~5 个,60% 的订单包含 1~2 个商品,30% 包含 3~4 个,10% 包含 5 个
3% 的 totalAmount 应为 null(模拟数据异常)
createdAt 时间范围在最近 30 天内
(3)将“真实性检查清单”写进 Prompt
我在 Prompt 的最后通常会加上一段自检指令,让 Claude Code 在生成后自我审查。虽然前面说过 AI 自我验证不太可靠,但在生成阶段加入自检指令,确实能减少一部分初级错误。例如:
“生成完成后,请自行检查:每条数据是否满足以上所有规则?如果发现违反规则的数据,请重新生成直到全部满足。”
第二阶段:数据生成,迭代而非一步到位
不要期望一次性生成完美的 Mock 数据集。现实中的有效流程是:
- 第一次生成:生成少量数据(5~10 条),人工走读。
- 规则补充:发现遗漏的约束后,修改 Prompt 重新生成。
- 第二次生成:生成中等规模数据(50~100 条),进行自动化 Schema 校验。
- 分布微调:检查数据分布是否符合预期,如果不符,调整分布描述再次生成。
- 最终生成:生成目标数量,并进行完整验证。
这个过程通常需要 2~3 个循环,每个循环耗时大约 3~5 分钟(包括生成和人工抽查)。相较于手写同等数量和复杂度的 Mock 数据(通常需要数小时),效率提升是数量级的。

第三阶段:自动验证,用代码保证真实性落地
生成的 Mock 数据不能只靠肉眼判断,必须建立自动验证流水线。我的团队搭建了一个简单的校验工具链:
第一步:Schema 校验
使用 JSON Schema Validator(如 Ajv)对生成的 JSON 文件进行校验,确保所有字段类型、必填项、格式正确。这一步通常 100% 通过。
第二步:自定义规则校验(最关键)
编写断言脚本,用代码验证业务规则。例如:
// 验证 totalAmount 计算是否正确
orders.forEach(order => {
const itemTotal = order.items.reduce((sum, item) => sum + item.quantity * item.unitPrice, 0);
const expectedTotal = itemTotal >= 99 ? itemTotal : itemTotal + 8;
assert(order.totalAmount === expectedTotal, 金额计算错误: ${order.orderId});
});
// 验证状态与字段一致性
orders.forEach(order => {
if (order.status === 'cancelled') {
assert(!order.paidAt, 已取消订单不应有支付时间: ${order.orderId});
}
});
这种规则校验脚本是一次性编写的,但可以复用到后续的所有 Mock 数据生成中。我们建立了一个规则库,按业务域分类,现在新项目接入时,只需挑选合适的规则脚本即可,不再从零编写。
第三步:分布可视化抽查
对于重要的 Mock 数据集,我们会用简单的 Python 脚本画出分布直方图,和线上采样数据进行目视对比。这并非自动化,但对发现系统性偏差非常有效。
第四步:集成到测试流水线
最终,将校验脚本接入 CI 流程。每次生成新的 Mock 数据后,必须通过校验脚本才能被测试用例使用。这样做的好处是,未来如果有人修改了 Mock 数据或重新生成,质量不会退化。
七、不同场景下的取舍:何时信任 AI 生成,何时必须人工干预
尽管我们构建了以上完整的流程,但在真实工作中,不是所有测试数据都需要达到四个维度的最高标准。根据场景的不同,我们做了明确的取舍策略,避免过度投入。
场景一:低风险的查询类接口测试
特征:只读操作,不涉及数据写入或状态变更,测试重点在于过滤、排序、分页逻辑的正确性。
真实性要求:结构真实性必须达到 100%,逻辑一致性达到 80% 即可(如金额计算不必精确,只要不为空),分布真实性不需要,行为仿真不需要。
做法:使用最简单的 Prompt,只提供 Schema 和基本字段说明,让 Claude Code 快速生成。无需校验规则脚本,人工抽查 2~3 条即可。
原因:这类测试的验证点在于代码逻辑本身,Mock 数据只要不引起空指针或类型异常就不会干扰测试结果。追求高真实性在这里是浪费。
场景二:核心业务的写操作接口测试
特征:涉及订单创建、支付、退款、账务处理等核心交易逻辑,测试需要覆盖复杂的状态机、金额计算和异常路径。
真实性要求:四个维度全部需要达到高标。结构真实性 100%,逻辑一致性 95% 以上,分布真实性 80% 以上(尤其关注金额和状态分布),行为仿真性必须覆盖所有状态迁移路径。
做法:使用完整的四阶段流程(结构→规则→分布→行为),编写详细的规则校验脚本,并在 CI 中强制执行。这是 Mock 数据投入成本最高的场景,但也是收益最大的。
原因:这里的任何数据失真都可能导致生产事故。我们的支付系统在重构后,Mock 数据校验脚本在回归测试中拦截了 3 次因代码变更导致的数据不兼容问题,避免了线上故障。

场景三:性能测试或压力测试
特征:需要海量 Mock 数据(百万级以上),数据的业务精确度要求不高,但数据量的级和分布特征必须与生产环境匹配。
真实性要求:结构真实性 100%,逻辑一致性要求低(可全为简单的合法数据),分布真实性极为重要(必须与线上分布一致,否则测出的性能曲线毫无意义),行为仿真不需要。
做法:先小批量(1000 条)用 Claude Code 生成带分布规则的 Mock 数据模板,然后用批量生成脚本复制并微调,而不是直接让 Claude Code 生成百万条数据(成本高且耗时)。
原因:性能测试的核心瓶颈在数据量和分布,而非每一条数据的精细度。我们测试查询接口的 P99 延迟时,如果 Mock 数据的订单状态分布与线上不一致,最终测出来的慢查询优化方向可能完全偏掉。
场景四:演示、原型或 Demo
特征:给产品经理或客户展示界面效果,数据只需“看起来像真的”即可。
真实性要求:仅结构真实性 + 视觉真实性(如人名、地名真实感)。逻辑一致性较低的失真在演示中不会被察觉。
做法:用 Faker 库 + Claude Code 生成少量富文本描述性数据(如商品评价长文本、用户头像 URL 等),追求“好看”而非“精确”。
八、重新看待“真实性”:不是目标,而是手段
经过这半年的实践和反思,我对“Mock 数据的真实性”这件事的认知,发生了一个重要的转变。
最初,我把“真实性”当成一个静态的质量目标,数据越接近生产环境越好。但现在我更愿意把它看成一种策略工具。不同的测试目的,需要不同“形状”的数据真实。有时我们需要逼真到毫厘,有时我们需要故意不真(比如刻意构造异常数据)。
Claude Code 真正的价值,不是它生成的 Mock 数据本身有多真,而是它给了我们一种快速控制“真与假比例”的能力。 在过去,我们只有两种选择:要么花大力气手工造真数据,要么用简单的随机假数据凑合。现在,通过 Claude Code,我们可以精准地调节数据的真实性维度,为不同的测试场景定制数据。
比如,我们在开发一个新的反欺诈模型时,需要测试它对三种欺诈模式的检出率。如果用完全真实的 Mock 数据,欺诈样本太少,测试不充分。如果用完全随机的假数据,模型可能学到错误的模式。我们最终的方案是:让 Claude Code 按照真实业务特征为基础,但刻意放大某些欺诈特征的比例(如高频小额交易、异地登录、设备指纹变化),构造出一个“半真半假”的增强数据集。 这个数据集的真实分布与线上不同,但它精确地服务于我们的测试目标,检测极端情况下的模型表现。
这种“真实性可调”的 Mock 数据生成能力,是传统手段无法实现的。

最后一步:我建议你这样开始
如果你读完这篇文章,决定在你的项目里尝试提升 Mock 数据的真实性,我不建议你一次性引入全套流程。从一个小切口开始,快速拿到正向反馈,再逐步推广。
以下是我建议的三步启动计划:
第一步:选取一个你最头疼的接口(明天就做)
找一个你们系统中逻辑最复杂、最常出 bug 的接口,用上面提到的四维框架重新审视你们现有的 Mock 数据。很可能你会发现,那些反复出现的生产问题,在测试数据里早就埋下了隐患。
花半个小时,为这个接口写一份“业务规则补充”文档,粘贴给 Claude Code,生成 20 条新 Mock 数据,和旧数据做个对比。这个对比本身,就足以说服你自己(和你的团队)投入更多精力在这件事上。
第二步:建立你的第一条校验规则(本周内完成)
选取一个最常见的业务规则(比如“订单金额等于商品金额之和”),写一段校验脚本,挂到 CI 里。脚本不需要完美,哪怕只检查一个字段,也会让你立刻体会到自动化校验的安全感。
一个月后,你会发现你的规则库在自然生长。每遇到一个新的 bug,你就往库里加一条新规则,渐渐形成一套完整的防御网。
第三步:把 Prompt 模板化,让整个团队复用(两周内)
把你为第一个接口写的那份“三层 Prompt 框架”抽象成模板,放到团队 Wiki 里。鼓励其他同事在使用 Claude Code 生成 Mock 数据时,遵循这个模板。你不需要强迫任何人改变工作方式,只要让他们看到你用这种方法产出的测试更稳定、发现的问题更多,影响就会自然扩散。

最后说一句题外话。这半年来,AI 辅助编程的讨论热火朝天,但我发现一个现象:我们聊了很多“AI 能帮我写多少代码”,却很少聊“AI 写出来的代码是否正确”。Mock 数据的真实性,只是这个巨大问题的一个微小侧面。在测试这个领域,速度从来不是第一追求,可信才是。 Claude Code 可以极大地提升我们生成测试数据的速度,但如果我们不去刻意追求“真实性”,速度越快,我们积累的技术债务可能也越多,只不过这些债务埋在了测试代码里,更难被发现。
所以,下次当你让 AI 帮你生成 Mock 数据时,请多问自己一句:这些数据,真的能代表真实世界的混乱与复杂吗?如果答案模糊,那就值得你再花几分钟,把 Prompt 写得再详细一点,把校验脚本加得再严格一点。这几分钟的投资,将在未来的每一次测试执行中,为你守护代码质量的底线。
常见问题解答(FAQ)
1. Claude Code生成Mock数据时,如何避免数据过于随机而失去业务语义?
我最近在用Claude Code帮我写单元测试的Mock数据,但发现它生成的字段值虽然格式正确,却经常不符合实际业务逻辑。比如用户的年龄可能填了150岁,或者邮箱后缀全是乱编的。我想知道有没有办法让生成的Mock数据更有“真实感”,而不是一堆随机拼凑的值。
核心在于给Claude Code提供业务约束上下文。我踩过一个坑:只给了一个JSON Schema,结果生成了大量理论可行但实际无意义的数据。后来我在Prompt里加入显式规则,比如“年龄必须在18-65之间,且遵循正态分布”、“邮箱域名统一为@company.com”。
更有效的方式是附上一份真实样本数据(脱敏后)做参考,Claude Code会模仿样本的统计特征。我的经验是,用一段50行左右的真实数据片段作为few-shot示例,生成的Mock数据在分布和异常值频率上明显更贴近生产环境。不过需要注意,样本不能包含敏感字段,否则有隐私风险。
2. 如何让Claude Code生成的Mock数据符合复杂的业务关联性?
我经常需要Mock多个关联表的数据,比如订单系统里订单要关联用户、商品、地址。Claude Code单独生成每个表的数据没问题,但生成后订单里的用户ID经常指向不存在的用户,或者订单金额与商品价格相乘对不上。我想知道怎么控制它生成有关联逻辑的数据。
Claude Code无法自动理解隐式关联,你必须把关系显式表达在Prompt中。我的做法是定义一个完整的数据模型,包括外键和计算规则。比如要求“生成5个用户(ID从1到5)和10个订单,每个订单的userId必须是存在的用户ID,且订单总价等于商品单价×数量”。
更进阶的方式是用伪代码描述业务逻辑,像‘订单状态流转:支付后状态为paid,发货后为shipped’。我最近在做一个库存扣减的测试,让Claude Code生成一组操作序列(先创建订单再扣库存),它生成的Mock数据序列在逻辑上可行,但需要人工跑一遍所有断言来验证。
这个环节建议写一个自动校验脚本,检查外键和计算字段的一致性。
3. Claude Code生成的Mock数据在边界值覆盖方面是否比手动编写更可靠?
手动写Mock数据时我经常忘记覆盖边界情况,比如空字符串、负数、超大文本等。Claude Code能自动生成这些边界值吗?我试了几次,它倾向于生成常规值,但好像不会主动考虑边界。有没有办法让它在生成时系统性地覆盖边界条件?
直接让Claude Code生成边界值效果很差,因为它默认追求“正常”。我的做法是在Prompt里明确定义边界规则,比如“每个字段至少包含一个合法最大值、最小值、空值以及特殊字符的实例”。我曾经在一个金融系统的测试中,手动写了一份边界检查清单,然后让Claude Code按清单生成。
它一次就产出了符合要求的Mock数据,覆盖了负利率、极高本息和精度截断等几十个边界。相比人肉枚举,Claude Code的速度优势明显,但前提是你得把边界逻辑描述清楚。我常用的技巧是先列一个边界值表格(给Prompt看),然后让Claude Code按表格逐行生成,这样不会漏项。
不过要注意,AI生成的边界数据可能包含语义矛盾(比如年龄0岁但已有订单),需要额外校验。
4. 在使用Claude Code生成Mock数据时,如何确保数据不会泄露真实生产环境的敏感信息?
我担心如果直接把生产数据库的SQL导出给Claude Code做参考,它可能会在生成的Mock数据里保留真实客户的姓名、手机号等敏感信息。就算用Prompt约束,万一它记住了怎么办?而且我听说有些AI工具会在训练数据中混入用户输入。怎么在追求真实性的同时保证隐私安全?
这是非常现实的风险。我的原则是:绝不要将任何包含真实PII的数据传给Claude Code。我会先用脚本对生产数据进行脱敏,姓名替换为占位符,手机号随机化,身份证后4位打星号等。然后才把脱敏后的样本作为参考。
另外建议使用Claude Code的Projects功能,将业务规则写入项目指令,而不直接依赖真实样本。我经历过一次差点泄露的事件:在Prompt里粘贴了一段真实的用户评论,Claude Code生成的Mock数据里包含了一个完整手机号。后来我强制要求在Prompt之前运行一个脱敏步骤。
最终我的工作流是:先有业务Schema和脱敏样本→Claude Code生成→人工抽查敏感字段→再接入测试。这样既保证了数据真实性(脱敏后仍保留分布特征),又规避了合规风险。
核心关键词
文章版权归“万象方舟”www.vientianeark.cn所有。发布者:程, 沐沐,转载请注明出处:https://www.vientianeark.cn/p/601212/
温馨提示:文章由AI大模型生成,如有侵权,联系 mumuerchuan@gmail.com 删除。
读者评论
这篇文章点醒我了,以前总觉得Mock数据格式对就行,原来忽略了跨字段的逻辑关联,这种“格式真业务假”的坑我踩过不止一次。
把Mock数据真实性拆解成四个维度来评估,这个方法论很实用,特别是结构真和逻辑真的区分,我们团队正好可以用上。
关于AI生成数据再用AI验证那段,说得太对了,深度神经网络目前还做不了业务规则校验,最后还是得靠人工和自动化规则。
Faker这类库确实很难模拟业务状态分布,Claude Code能理解自然语言规则、生成有偏数据,这点是传统工具做不到的。
从支付系统退票这个真实案例切入,一下子就解释清楚了为什么Mock不能只看格式,很有说服力,希望后面能多分享这类高风险场景的经验。