C# Bogus伪数据生成方法 C#如何为测试生成大量的假数据

来源:这里教程网 时间:2026-02-21 17:42:21 作者:

为什么 Bogus 生成的数据在测试中经常“不生效”

多数人用

Bogus
时直接 new
Faker<t>()</t>
就开始
Generate()
,结果发现:数据库插入失败、API 校验报错、时间字段超出范围。根本原因不是数据“假”,而是默认配置和业务场景脱节——
Faker
默认生成全量字段(包括可能为空的引用类型)、日期从 1970 年起、字符串长度随机且无业务语义。

实操建议:

显式调用
RuleFor
覆盖关键字段,尤其
Id
CreatedAt
Email
等有约束的属性
StrictMode(true)
提前暴露未映射字段(避免后期因新增属性导致静默空值)
DateTime
字段统一设范围:
ruleFor(x => x.CreatedAt, f => f.Date.Between(DateTime.Now.AddYears(-2), DateTime.Now))
禁用默认构造:传入
new Faker<user>().UseConstructor(() => new User())</user>
,防止
default(User)
触发意外初始化逻辑

如何批量生成带关联关系的假数据(比如订单+订单项)

单表 faker 很容易,但真实测试常需主子结构一致(如一个

Order
对应多个
OrderItem
,且
OrderItem.OrderId
必须等于父级
Id
)。Bogus 本身不自动维护跨对象引用,得手动桥接。

实操建议:

先生成主对象列表,再用
SelectMany
展开子对象,并在子对象
RuleFor
中捕获外键值:
f.RuleFor(x => x.OrderId, _ => order.Id)
避免在
Faker<orderitem></orderitem>
内部直接引用外部变量(闭包陷阱),改用
CustomInstantiator
或工厂方法传参
若关系复杂(如多层嵌套),优先用
Faker.GenerateLazy(n)
+
ToList()
控制内存,防止
IEnumerable
延迟执行引发重复生成
示例片段:
var orders = new Faker<Order>()
  .RuleFor(x => x.Id, f => f.IndexFaker)
  .Generate(100);
var orderItems = orders.SelectMany(order =>
  new Faker<OrderItem>()
    .RuleFor(x => x.OrderId, _ => order.Id)
    .RuleFor(x => x.ProductName, f => f.Commerce.ProductName())
    .Generate(3)
);

中文支持与业务字段定制的关键配置

默认

Bogus
是英文语料,直接生成
UserName
是 “Lance Kirlin”,对中文系统测试几乎无用;更麻烦的是,像“手机号”“身份证号”“省市地址”等强规则字段,官方没内置,必须自己补。

实操建议:

切换本地化:构造
Faker
时传入
new CultureInfo("zh-CN")
,可让姓名、地址、公司名等自动转中文(但注意:部分 provider 如
Commerce.ProductName()
仍为英文)
手机号用正则生成:
f.Random.ReplaceNumbers("1##-####-####")
,比
f.Phone.PhoneNumber()
更可控
身份证号需校验算法,别手写——推荐用 NuGet 包
Z.ExtensionMethods
GenerateIdCard()
,或封装一个带校验位计算的静态方法
避免在
RuleFor
中调用耗时操作(如 HTTP 请求、文件读取),Bogus 是同步批量生成,阻塞会拖慢整个测试集

性能瓶颈在哪?10 万条数据生成慢的常见原因

生成 1000 条很快,但到 10 万条明显卡顿,往往不是 Bogus 本身慢,而是生成逻辑里混入了隐式开销。

实操建议:

禁用
Faker.StrictMode
(调试期开,压测期关),它每次生成都反射检查属性,10 万次就是 10 万次反射
不要在
RuleFor
里反复 new 同一个
Faker
实例(如
f => new Faker<address>().Generate()</address>
),改为复用单例
Faker<address> addressFaker = new();</address>
字符串字段慎用
f.Lorem.Sentence()
(随机句长 + 标点处理),换成
f.Lorem.Word(5)
固定词数,性能差 3–5 倍
若需导出 CSV/JSON,别用
JsonSerializer.Serialize(list)
一次性序列化,改用
System.Text.Json.Utf8JsonWriter
流式写入,内存占用直降 70%

真正难的不是生成“假数据”,而是生成“像真数据一样被系统信任”的数据——字段约束、关联一致性、业务语义、性能边界,每个点漏掉一点,测试就离真实环境远一分。

相关推荐