Heim >Web-Frontend >js-Tutorial >Erstellen eines TypeScript-Helfers für die Generierung von Scheindaten mit Zod und Faker

Erstellen eines TypeScript-Helfers für die Generierung von Scheindaten mit Zod und Faker

Patricia Arquette
Patricia ArquetteOriginal
2024-11-07 18:52:02911Durchsuche

Building a TypeScript Helper for Mock Data Generation with Zod and Faker

Beim Erstellen von Anwendungen können Scheindaten für Tests, Entwicklung und Prototyping von unschätzbarem Wert sein. Mit der robusten Schemavalidierung von Zod und den Datengenerierungsfunktionen von Faker können wir einen leistungsstarken Helfer erstellen, um realistische, schemakonforme Scheindaten für jedes Zod-Schema zu generieren.

Einführung

In diesem Leitfaden erstellen wir eine Hilfsfunktion „generateMockDataFromSchema“, die ein Zod-Schema akzeptiert und Scheindaten zurückgibt, die der Struktur und den Validierungsregeln des Schemas entsprechen. Lass uns Schritt für Schritt eintauchen!

Artikel-Komplettlösung

  • Einführung
  • Artikel-Komplettlösung
  • Codeausschnitte
  • Warum Zod und Faker für Scheindaten verwenden?
  • Erstellen des Scheindatengenerators
    • Die Hilfsfunktion „generateMockDataFromSchema“
    • Umgang mit jedem Schematyp
      • Strings mit spezifischen Anforderungen
      • Numerische Werte
      • Boolesche Werte
      • Arrays
      • Optionale und Nullable-Felder
      • Objekte mit verschachtelten Feldern
    • Beispielverwendung
    • Anpassungsoptionen hinzufügen
    • Testen der Hilfsfunktion
  • Fazit

Codeausschnitte

  • Mock Data Generator-Hilfsfunktion
  • Beispiel Stackblitz reagieren

Warum Zod und Faker für Scheindaten verwenden?

Bevor wir mit dem Codieren beginnen, besprechen wir, warum Zod und Faker perfekt für diese Aufgabe geeignet sind:

  • Zod: Bietet eine robuste, typsichere Möglichkeit, Datenschemata in TypeScript zu definieren. Seine Schemavalidierungsfunktionen stellen sicher, dass unsere Scheindaten bestimmten Regeln wie E-Mail-Formaten, UUIDs oder Mindest-/Höchstwerten entsprechen.

  • Faker: Erzeugt realistische Zufallsdaten wie Namen, Daten, E-Mails und URLs. Dies ist besonders nützlich, wenn wir Scheindaten benötigen, die realen Szenarien ähneln, sodass sie sich perfekt für Test- und Demozwecke eignen.

Die Kombination von Zod und Faker gibt uns die Möglichkeit, Scheindaten zu erstellen, die sowohl realistisch als auch schemakonform sind.

Erstellen des Scheindatengenerators

Das Herzstück unserer Lösung ist die Hilfsfunktion „generateMockDataFromSchema“, die ein Zod-Schema interpretieren und passende Scheindaten generieren kann. Diese Funktion verarbeitet verschiedene Datentypen (Zeichenfolge, Zahl, Array, Objekt) und berücksichtigt Validierungseinschränkungen innerhalb jedes Schematyps. Lassen Sie uns untersuchen, wie es aufgebaut ist.

 Die „generateMockDataFromSchema“-Hilfsfunktion

Die Funktion „generateMockDataFromSchema“ akzeptiert zwei Parameter:

  • Schema: Ein Zod-Schema, das die Form und Regeln für die Daten definiert.
  • Optionen (optional): Ein Objekt zum Anpassen von Array-Längen und optionalem Feldverhalten.

Hier ist die Funktion, unterteilt in die einzelnen Abschnitte, um die Handhabung verschiedener Schematypen zu erläutern.

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,
  });
}

Umgang mit jedem Schematyp

In genericMockDataFromSchema wird jeder Zod-Schematyp (wie ZodString, ZodNumber usw.) unterschiedlich behandelt, um seinen einzigartigen Anforderungen Rechnung zu tragen. Lassen Sie uns jeden Typ durchgehen.

Saiten mit besonderen Anforderungen

Für ZodString müssen wir alle spezifischen Prüfungen wie E-Mail, URL oder UUID berücksichtigen. Hier kommt unsere Hilfsfunktion handleStringCheck ins Spiel. Sie prüft das String-Schema und gibt, falls Prüfungen vorhanden sind, einen relevanten Scheinwert zurück (z. B. eine E-Mail für E-Mail, eine URL für URL). Wenn keine spezifischen Prüfungen gefunden werden, wird standardmäßig ein zufälliges Wort generiert.

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();
  }
};

In genericMockDataFromSchema verwenden wir diesen Helfer, um Daten für Zeichenfolgenfelder mit Prüfungen zu generieren.

Numerische Werte

Für ZodNumber generieren wir Ganzzahlen mit der Methode faker.number.int() von Faker. Dieser Teil kann weiter angepasst werden, um Minimal- und Maximalwerte zu verarbeiten, sofern diese im Schema definiert sind.

if (schema instanceof ZodNumber) {
  return faker.number.int() as T;
}

Boolesche Werte

Für boolesche Werte bietet Faker eine einfache Funktion faker.datatype.boolean(), um zufällig wahre oder falsche Werte zu generieren.

if (schema instanceof ZodBoolean) {
  return faker.datatype.boolean() as T;
}

Arrays

Beim Umgang mit ZodArray generieren wir rekursiv Scheindaten für jedes Element im Array. Wir ermöglichen auch die Anpassung der Array-Länge mithilfe des Optionsparameters.

Um Arrays zu generieren, bestimmen wir zunächst die Länge mithilfe von getArrayLength, einer Hilfsfunktion, die die Optionen auf minimale und maximale Länge prüft. Für jedes Array-Element wird „generateMockDataFromSchema“ rekursiv aufgerufen, um sicherzustellen, dass auch verschachtelte Schemata innerhalb von Arrays verarbeitet werden.

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,
  });
};

Optionale und Nullable-Felder

Optionale und Nullable-Felder werden behandelt, indem nach dem Zufallsprinzip entschieden wird, ob sie in die Ausgabe einbezogen werden sollen. Mit der Einstellung „options.optional.probability“ können wir diese Wahrscheinlichkeit steuern. Wenn ein Feld generiert wird, ruft es „generateMockDataFromSchema“ rekursiv für das innere Schema auf.

if (schema instanceof ZodOptional || schema instanceof ZodNullable) {
  const shouldGenerate =
    Math.random() > (options?.optional?.probability || 0.5);
  return shouldGenerate
    ? generateMockDataFromSchema(schema.unwrap(), options)
    : null;
}

Objekte mit verschachtelten Feldern

Für ZodObject iterieren wir über jedes Schlüssel-Wert-Paar und generieren rekursiv Daten für jedes Feld. Dieser Ansatz unterstützt tief verschachtelte Objekte und macht ihn dadurch äußerst flexibel.

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;
}

Beispielverwendung

Sobald „generateMockDataFromSchema“ installiert ist, sehen wir es uns in Aktion an. Hier ist ein Beispielschema, UserSchema, mit verschiedenen Typen, optionalen Feldern und verschachtelten Arrays.

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,
  });
}

Anpassungsoptionen hinzufügen

Die Funktion „generateMockDataFromSchema“ akzeptiert auch einen optionalen Optionsparameter, um Array-Längen und optionales Feldverhalten anzupassen. Hier ist ein Beispiel dafür, wie Sie diese Optionen verwenden können:

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();
  }
};

Dadurch wird sichergestellt, dass Array-Felder eine Länge zwischen 2 und 5 haben und optionale Felder mit einer Wahrscheinlichkeit von 70 % generiert werden.

Testen der Hilfsfunktion

Um zu bestätigen, dass „generateMockDataFromSchema“ wie erwartet funktioniert, erstellen Sie Komponententests für verschiedene Schemakonfigurationen. Hier ist ein Beispiel für einen Test für ein Array-Schema:

if (schema instanceof ZodNumber) {
  return faker.number.int() as T;
}

Indem Sie Tests für verschiedene Schematypen und Konfigurationen schreiben, können Sie sicherstellen, dass sich die Hilfsfunktion in verschiedenen Szenarien korrekt verhält.

Abschluss

Durch die Kombination von Zod und Faker haben wir einen leistungsstarken, wiederverwendbaren Scheindatengenerator erstellt, der auf TypeScript-Projekte zugeschnitten ist. Die Möglichkeit, verschiedene Szenarien zu testen und realistische Daten in Aktion zu sehen, macht es für schnelle Entwicklung und Qualitätstests von unschätzbarem Wert.

Das obige ist der detaillierte Inhalt vonErstellen eines TypeScript-Helfers für die Generierung von Scheindaten mit Zod und Faker. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn