Apabila membina aplikasi, data palsu boleh menjadi tidak ternilai untuk ujian, pembangunan dan prototaip. Dengan pengesahan skema Zod yang mantap dan keupayaan penjanaan data Faker, kami boleh mencipta pembantu yang berkuasa untuk menjana data olok-olok yang realistik dan mematuhi skema untuk mana-mana skema Zod.
Dalam panduan ini, kami akan mencipta fungsi pembantu generateMockDataFromSchema yang menerima skema Zod dan mengembalikan data palsu yang sepadan dengan struktur skema dan peraturan pengesahan. Mari selami langkah demi langkah!
Sebelum kita memulakan pengekodan, mari kita bincangkan sebab Zod dan Faker sesuai untuk tugasan ini:
Zod: Menyediakan cara yang teguh dan selamat jenis untuk menentukan skema data dalam TypeScript. Keupayaan pengesahan skemanya memastikan data palsu kami mematuhi peraturan khusus seperti format e-mel, UUID atau nilai minimum/maksimum.
Pemalsu: Menjana data rawak realistik seperti nama, tarikh, e-mel dan URL. Ini amat berguna apabila kami memerlukan data palsu yang menyerupai senario dunia sebenar, menjadikannya sempurna untuk tujuan ujian dan demo.
Menggabungkan Zod dan Faker memberi kami keupayaan untuk mencipta data palsu yang realistik dan mematuhi skema.
Inti penyelesaian kami ialah fungsi pembantu generateMockDataFromSchema, yang boleh mentafsir skema Zod dan menjana data olok-olok yang sepadan. Fungsi ini mengendalikan pelbagai jenis data (rentetan, nombor, tatasusunan, objek) dan menghormati kekangan pengesahan dalam setiap jenis skema. Mari terokai cara ia dibina.
Fungsi generateMockDataFromSchema menerima dua parameter:
Berikut ialah fungsinya, dipecahkan kepada setiap bahagian untuk menerangkan pengendalian jenis skema yang berbeza.
import { ZodSchema, ZodObject, ZodString, ZodNumber, ZodBoolean, ZodArray, ZodOptional, ZodNullable, ZodTypeAny, ZodStringCheck, } from "zod"; import { faker } from "@faker-js/faker"; import { z } from "zod"; const handleStringCheck = (check: ZodStringCheck) => { switch (check.kind) { case "date": return faker.date.recent().toISOString(); case "url": return faker.internet.url(); case "email": return faker.internet.email(); case "uuid": case "cuid": case "nanoid": case "cuid2": case "ulid": return crypto.randomUUID(); case "emoji": return faker.internet.emoji(); default: return faker.lorem.word(); } }; type GeneratorPrimitiveOptions = { array?: { min?: number; max?: number; }; optional?: { probability?: number; }; }; const getArrayLength = (options?: GeneratorPrimitiveOptions) => { return faker.number.int({ min: options?.array?.min || 1, max: options?.array?.max || 10, }); }; export function generateTestDataFromSchema<T>( schema: ZodSchema<T>, options?: GeneratorPrimitiveOptions ): T { if (schema instanceof ZodString) { const check = schema._def.checks.find((check) => handleStringCheck(check)); if (check) { return handleStringCheck(check) as T; } return faker.lorem.word() as T; } if (schema instanceof ZodNumber) { return faker.number.int() as T; } if (schema instanceof ZodBoolean) { return faker.datatype.boolean() as T; } if (schema instanceof ZodArray) { const arraySchema = schema.element; const length = getArrayLength(options); return Array.from({ length }).map(() => generateTestDataFromSchema(arraySchema) ) as T; } if (schema instanceof ZodOptional || schema instanceof ZodNullable) { const probability = options?.optional?.probability || 0.5; return ( Math.random() > probability ? generateTestDataFromSchema(schema.unwrap()) : null ) as T; } if (schema instanceof ZodObject) { const shape = schema.shape; const result: any = {}; for (const key in shape) { result[key] = generateTestDataFromSchema(shape[key] as ZodTypeAny); } return result as T; } throw new Error("Unsupported schema type", { cause: schema, }); }
Dalam generateMockDataFromSchema, setiap jenis skema Zod (seperti ZodString, ZodNumber, dll.) dikendalikan secara berbeza untuk mengambil kira keperluan uniknya. Mari kita lihat setiap jenis.
Untuk ZodString, kami perlu mempertimbangkan sebarang semakan khusus seperti e-mel, url atau uuid. Di sinilah fungsi pembantu kami handleStringCheck masuk. Ia memeriksa skema rentetan dan, jika ada semakan, mengembalikan nilai olok-olok yang berkaitan (cth., e-mel untuk e-mel, URL untuk url). Jika tiada semakan khusus ditemui, ia lalai untuk menjana perkataan rawak.
const handleStringCheck = (check: ZodStringCheck) => { switch (check.kind) { case "date": return faker.date.recent().toISOString(); case "url": return faker.internet.url(); case "email": return faker.internet.email(); case "uuid": case "cuid": case "nanoid": case "cuid2": case "ulid": return crypto.randomUUID(); case "emoji": return faker.internet.emoji(); default: return faker.lorem.word(); } };
Dalam generateMockDataFromSchema, kami menggunakan pembantu ini untuk menjana data bagi medan rentetan dengan semakan.
Untuk ZodNumber, kami menjana integer dengan kaedah faker.number.int() Faker. Bahagian ini boleh disesuaikan lagi untuk mengendalikan nilai minimum dan maksimum jika ia ditakrifkan dalam skema.
if (schema instanceof ZodNumber) { return faker.number.int() as T; }
Untuk boolean, Faker menawarkan fungsi faker.datatype.boolean() mudah untuk menjana nilai benar atau palsu secara rawak.
if (schema instanceof ZodBoolean) { return faker.datatype.boolean() as T; }
Apabila berurusan dengan ZodArray, kami menjana data palsu secara rekursif untuk setiap elemen dalam tatasusunan. Kami juga membenarkan menyesuaikan panjang tatasusunan menggunakan parameter pilihan.
Untuk menjana tatasusunan, kami mula-mula memutuskan panjang menggunakan getArrayLength, fungsi pembantu yang menyemak panjang minimum dan maksimum dalam pilihan. Untuk setiap elemen tatasusunan, generateMockDataFromSchema dipanggil secara rekursif, memastikan skema bersarang dalam tatasusunan turut dikendalikan.
type GeneratorPrimitiveOptions = { array?: { min?: number; max?: number; }; optional?: { probability?: number; }; }; if (schema instanceof ZodOptional || schema instanceof ZodNullable) { const probability = options?.optional?.probability || 0.5; return ( Math.random() > probability ? generateTestDataFromSchema(schema.unwrap()) : null ) as T; } const getArrayLength = (options?: GeneratorPrimitiveOptions) => { return faker.number.int({ min: options?.array?.min || 1, max: options?.array?.max || 10, }); };
Medan pilihan dan boleh dibatalkan dikendalikan dengan memutuskan secara rawak sama ada untuk memasukkannya dalam output. Tetapan options.optional.probability membolehkan kami mengawal kebarangkalian ini. Jika medan dijana, ia memanggil generateMockDataFromSchema secara rekursif untuk skema dalaman.
if (schema instanceof ZodOptional || schema instanceof ZodNullable) { const shouldGenerate = Math.random() > (options?.optional?.probability || 0.5); return shouldGenerate ? generateMockDataFromSchema(schema.unwrap(), options) : null; }
Untuk ZodObject, kami mengulangi setiap pasangan nilai kunci dan menjana data secara rekursif untuk setiap medan. Pendekatan ini menyokong objek bersarang dalam, menjadikannya sangat fleksibel.
if (schema instanceof ZodObject) { const shape = schema.shape; const result: any = {}; for (const key in shape) { result[key] = generateMockDataFromSchema(shape[key] as ZodTypeAny, options); } return result as T; }
Dengan generateMockDataFromSchema tersedia, mari lihat tindakannya. Berikut ialah contoh skema, UserSchema, dengan jenis yang berbeza, medan pilihan dan tatasusunan bersarang.
import { ZodSchema, ZodObject, ZodString, ZodNumber, ZodBoolean, ZodArray, ZodOptional, ZodNullable, ZodTypeAny, ZodStringCheck, } from "zod"; import { faker } from "@faker-js/faker"; import { z } from "zod"; const handleStringCheck = (check: ZodStringCheck) => { switch (check.kind) { case "date": return faker.date.recent().toISOString(); case "url": return faker.internet.url(); case "email": return faker.internet.email(); case "uuid": case "cuid": case "nanoid": case "cuid2": case "ulid": return crypto.randomUUID(); case "emoji": return faker.internet.emoji(); default: return faker.lorem.word(); } }; type GeneratorPrimitiveOptions = { array?: { min?: number; max?: number; }; optional?: { probability?: number; }; }; const getArrayLength = (options?: GeneratorPrimitiveOptions) => { return faker.number.int({ min: options?.array?.min || 1, max: options?.array?.max || 10, }); }; export function generateTestDataFromSchema<T>( schema: ZodSchema<T>, options?: GeneratorPrimitiveOptions ): T { if (schema instanceof ZodString) { const check = schema._def.checks.find((check) => handleStringCheck(check)); if (check) { return handleStringCheck(check) as T; } return faker.lorem.word() as T; } if (schema instanceof ZodNumber) { return faker.number.int() as T; } if (schema instanceof ZodBoolean) { return faker.datatype.boolean() as T; } if (schema instanceof ZodArray) { const arraySchema = schema.element; const length = getArrayLength(options); return Array.from({ length }).map(() => generateTestDataFromSchema(arraySchema) ) as T; } if (schema instanceof ZodOptional || schema instanceof ZodNullable) { const probability = options?.optional?.probability || 0.5; return ( Math.random() > probability ? generateTestDataFromSchema(schema.unwrap()) : null ) as T; } if (schema instanceof ZodObject) { const shape = schema.shape; const result: any = {}; for (const key in shape) { result[key] = generateTestDataFromSchema(shape[key] as ZodTypeAny); } return result as T; } throw new Error("Unsupported schema type", { cause: schema, }); }
Fungsi generateMockDataFromSchema juga menerima parameter pilihan pilihan untuk menyesuaikan panjang tatasusunan dan tingkah laku medan pilihan. Berikut ialah contoh cara anda boleh menggunakan pilihan ini:
const handleStringCheck = (check: ZodStringCheck) => { switch (check.kind) { case "date": return faker.date.recent().toISOString(); case "url": return faker.internet.url(); case "email": return faker.internet.email(); case "uuid": case "cuid": case "nanoid": case "cuid2": case "ulid": return crypto.randomUUID(); case "emoji": return faker.internet.emoji(); default: return faker.lorem.word(); } };
Ini akan memastikan medan tatasusunan mempunyai panjang antara 2 dan 5, dan medan pilihan dijana dengan kebarangkalian 70%.
Untuk mengesahkan bahawa generateMockDataFromSchema berfungsi seperti yang diharapkan, buat ujian unit untuk konfigurasi skema yang berbeza. Berikut ialah contoh ujian untuk skema tatasusunan:
if (schema instanceof ZodNumber) { return faker.number.int() as T; }
Dengan menulis ujian untuk pelbagai jenis dan konfigurasi skema, anda boleh memastikan bahawa fungsi pembantu berfungsi dengan betul dalam senario yang berbeza.
Dengan menggabungkan Zod dan Faker, kami telah mencipta penjana data olok-olok yang berkuasa dan boleh digunakan semula yang disesuaikan dengan projek TypeScript. Keupayaan untuk menguji senario yang berbeza dan melihat data yang realistik dalam tindakan menjadikannya tidak ternilai untuk pembangunan pesat dan ujian kualiti.
Atas ialah kandungan terperinci Membina Pembantu TypeScript untuk Penjanaan Data Olok-olok dengan Zod dan Faker. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!