工程效率与质量 / 入门
测试数据 Builder:让用例只表达与场景有关的差异
用合理默认值和链式覆盖生成测试对象,避免每次模型加字段都修改整套测试。
测试夹具为什么越来越难读
直接在每条用例里写完整对象,会把场景相关字段淹没在样板数据中。模型新增必填字段后,几十条无关测试也要跟着改。Builder 把合法默认值集中管理,让用例只覆盖影响当前行为的字段。
EXAMPLE / 01测试数据
const anOrder = (overrides: Partial<Order> = {}): Order => ({
id: 'order-1',
status: 'PENDING',
total: 100,
currency: 'CNY',
items: [{ skuId: 'sku-1', quantity: 1 }],
...overrides
});默认值必须合法但不神奇
默认对象应通过领域校验,并尽量使用普通值。不要让默认值碰巧触发折扣、时区边界或特殊权限,否则无关测试会产生隐蔽耦合。需要特殊场景时,用命名方法明确表达。
EXAMPLE / 02测试数据
const expiredCoupon = () =>
aCoupon({
code: 'OLD10',
expiresAt: new Date('2020-01-01T00:00:00Z')
});随机数据要能复现
属性测试或唯一约束场景可以使用随机数据,但必须记录 seed。普通业务测试更适合固定、可读的值。失败信息里应直接显示最终构建对象,减少排查时来回跳转。
默认对象始终满足领域约束;特殊状态通过具名方法创建;日期明确指定时区;随机生成器支持固定 seed。