
如何在多个 locale 的 faker 实例间共享同一个 Randomizer 保持数据可复现【免费下载链接】fakerGenerate massive amounts of fake data in the browser and node.js项目地址: https://gitcode.com/GitHub_Trending/faker/faker用faker-js/faker生成测试数据时如果你需要同时从两个 locale 取值例如一个中文人名加一个英文人名给每个Faker实例各自seed会遇到可复现性问题只给其中一个实例播种时另一个实例的值无法复现。官方 Randomizer 指南 给出的解决办法是只构造一个Randomizer把它传给所有Faker实例这样只需对共享的Randomizer播种一次就能同时控制所有实例的随机序列保证每次运行输出一致。问题两个独立实例各自 seed 为什么不可靠指南中给出的典型场景是一个中文用户可能有一个英文身份需要分别生成两个 locale 的数据。用两个独立实例时写法如下文档示例import { fakerEN, fakerZH_TW } from faker-js/faker; fakerZH_TW.seed(5); fakerEN.seed(5); const firstName fakerZH_TW.person.firstName(); // 炫明 const alias fakerEN.person.firstName(); // Arthur这段代码的隐患在于只给其中一个实例播种时可复现性无法保证。指南特别指出当播种发生的位置和数据生成的位置不同例如代码有嵌套、调用顺序分散时这个问题会更突出。如何创建并共享一个 RandomizerRandomizer必须在构造Faker实例时通过配置传入。Faker 内置两种基于 MersenneTwister19937 的Randomizer来源src/utils/mersenne.tsimport { generateMersenne32Randomizer, // Default prior to v9 generateMersenne53Randomizer, // Default since v9 } from faker-js/faker; const randomizer generateMersenne53Randomizer();两者的区别按文档说明32 位的更快53 位生成的随机值质量更好重复值显著更少。不传randomizer时Faker默认使用generateMersenne53Randomizer()。接受Randomizer的构造入口有两个来源src/randomizer.tsnew SimpleFaker(...)new Faker(...)Randomizer接口只有两个方法next()生成一个[0, 1)区间的随机浮点数seed(seed: number | number[])设置种子。接口注释明确要求实例在传给任何 Faker 构造函数之前必须处于可用状态包括已经seed()过随机值或固定值均可。执行步骤把同一个 Randomizer 传给所有实例安装依赖Node.js 或浏览器项目均可npm install --save-dev faker-js/faker下面的代码把同一个randomizer传入两个不同 locale 的Faker实例import { en, Faker, Randomizer, zh_TW } from faker-js/faker; const randomizer: Randomizer ...; // 任一已 seed 的 Randomizer 实例 const customFakerEN new Faker({ locale: en, randomizer, }); const customFakerZH_TW new Faker({ locale: [zh_TW, en], randomizer, }); randomizer.seed(5); // customFakerEN.seed(5); // Redundant // customFakerZH_TW.seed(5); // Redundant const firstName customFakerZH_TW.person.firstName(); // 炫明 const alias customFakerEN.person.firstName(); // John (different from before, because it is now the second call)代码中有两个容易踩的点都来自文档原文播种只对randomizer做一次即可再对各实例调.seed()是冗余的代码注释标注 Redundant。随机序列是跨实例共享消耗的第二个实例取到的值是序列里的下一次取值。所以上例中alias是John而不是独立实例示例里的Arthur注释解释了原因就是it is now the second call。另外注意第二个实例的locale写作[zh_TW, en]数组形式表示zh_TW缺失的定义回退到en。如何验证可复现性Faker构造函数支持seed选项src/core.ts 中的FakerOptions当同时传入randomizer和seed时构造时会执行randomizer.seed(seed)。因此验证方式就是固定种子、固定调用顺序然后运行两次比对结果import { en, Faker, generateMersenne53Randomizer, zh_TW } from faker-js/faker; function makeFakers() { const randomizer generateMersenne53Randomizer(5); // 固定种子 const zhTw new Faker({ locale: [zh_TW, en], randomizer }); const enOnly new Faker({ locale: en, randomizer }); return { zhTw, enOnly }; } const a makeFakers(); const b makeFakers(); console.log(a.zhTw.person.firstName() b.zhTw.person.firstName()); console.log(a.enOnly.person.firstName() b.enOnly.person.firstName());两次运行或两个以相同顺序取值的实例组应输出true。判断依据是 使用指南 中Reproducible results一节的同一原则faker.seed(123)之后再次faker.seed(123)会重置序列两次取到相同的faker.number.int()。有一个限制需要知道使用相对日期的方法即使设了种子也不可复现例如faker.date.past、faker.date.future、faker.date.recent、faker.date.soon、faker.git.commitEntry和faker.string.uuid({ version: 7 })因为它们默认以今天为基准。要让这些方法也可复现需要指定固定的参照日期// creates a date soon after 2023-01-01 faker.date.soon({ refDate: 2023-01-01T00:00:00.000Z });或为所有此类方法设置默认参照日期来源docs/guide/usage.md// affects all future faker.date.* calls faker.setDefaultRefDate(2023-01-01T00:00:00.000Z);限制与备选路径默认 Randomizer 已够用文档明确提示只有当你有明确目标例如与其他实例/工具共享同一个随机生成器时才需要改Randomizer。升级版本可能改变取值指南说明升级到新版本 Faker 时即使种子相同由于底层数据名字、词语列表等可能变化取值也可能不同。第三方 Randomizer如果你希望用纯外部库如 pure-rand的随机源可以自己实现Randomizer接口再传入构造函数。文档给出一个 pure-rand 的示例实现并声明Faker 不为第三方库提供桥接示例只展示接口如何实现、未经正确性测试来源docs/guide/randomizer.mdimport { Faker, Randomizer, SimpleFaker } from faker-js/faker; import { RandomGenerator, xoroshiro128plus } from pure-rand; export function generatePureRandRandomizer( seed: number | number[] Date.now() ^ (Math.random() * 0x100000000), factory: (seed: number) RandomGenerator xoroshiro128plus ): Randomizer { const self { next: () (self.generator.unsafeNext() 0) / 0x100000000, seed: (seed: number | number[]) { self.generator factory(typeof seed number ? seed : seed[0]); }, } as Randomizer { generator: RandomGenerator }; self.seed(seed); return self; }把同一个共享Randomizer传给所有 locale 实例、只对它播种一次、必要时配合固定refDate多 locale 场景下的可复现链路即告完成需要复现测试时按固定种子 固定调用顺序 两次运行比对验证即可。【免费下载链接】fakerGenerate massive amounts of fake data in the browser and node.js项目地址: https://gitcode.com/GitHub_Trending/faker/faker创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考