ホームページ >ウェブフロントエンド >jsチュートリアル >Zod と Faker を使用したモックデータ生成用の TypeScript ヘルパーの構築

Zod と Faker を使用したモックデータ生成用の TypeScript ヘルパーの構築

Patricia Arquette
Patricia Arquetteオリジナル
2024-11-07 18:52:02928ブラウズ

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

アプリケーションを構築する場合、モック データはテスト、開発、プロトタイピングに非常に貴重です。 Zod の堅牢なスキーマ検証と Faker のデータ生成機能を使用すると、あらゆる Zod スキーマに対して現実的でスキーマに準拠したモック データを生成する強力なヘルパーを作成できます。

導入

このガイドでは、Zod スキーマを受け入れ、スキーマの構造と検証ルールに一致するモック データを返すヘルパー関数generateMockDataFromSchema を作成します。段階的に見ていきましょう!

記事のチュートリアル

  • はじめに
  • 記事のチュートリアル
  • コードのスニペット
  • モックデータに Zod と Faker を使用する理由
  • モックデータジェネレーターの作成
    • generateMockDataFromSchema ヘルパー関数
    • 各スキーマタイプの処理
      • 特定の要件を持つ文字列
      • 数値
      • ブール値
      • 配列
      • オプションのフィールドと Null 許容フィールド
      • ネストされたフィールドを持つオブジェクト
    • 使用例
    • カスタマイズ オプションの追加
    • ヘルパー関数のテスト
  • 結論

コードのスニペット

  • モックデータジェネレーターヘルパー関数
  • React の例 Stackblitz

モックデータに Zod と Faker を使用する理由

コーディングを始める前に、Zod と Faker がこのタスクに最適である理由を説明しましょう:

  • Zod: TypeScript でデータ スキーマを定義するための堅牢でタイプセーフな方法を提供します。スキーマ検証機能により、模擬データが電子メール形式、UUID、最小値/最大値などの特定のルールに準拠していることが保証されます。

  • Faker: 名前、日付、電子メール、URL などの現実的なランダム データを生成します。これは、現実世界のシナリオに似た模擬データが必要な場合に特に便利で、テストやデモの目的に最適です。

Zod と Faker を組み合わせることで、現実的でスキーマに準拠したモック データを作成できます。

モックデータジェネレーターの作成

私たちのソリューションの中心となるのは、Zod スキーマを解釈して、一致するモック データを生成できるgenerateMockDataFromSchema ヘルパー関数です。この関数はさまざまなデータ型 (文字列、数値、配列、オブジェクト) を処理し、各スキーマ型内の検証制約を尊重します。どのように構築されているか見てみましょう。

 generateMockDataFromSchema ヘルパー関数

generateMockDataFromSchema 関数は 2 つのパラメーターを受け入れます:

  • schema: データの形状とルールを定義する Zod スキーマ。
  • options (オプション): 配列の長さとオプションのフィールドの動作をカスタマイズするためのオブジェクト。

ここでは、関数を各セクションに分けて、さまざまなスキーマ タイプの処理を説明します。

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

各スキーマタイプの処理

generateMockDataFromSchema では、各 Zod スキーマ タイプ (ZodString、ZodNumber など) は、その固有の要件に応じて異なる方法で処理されます。それぞれのタイプを見てみましょう。

特定の要件を持つ文字列

ZodString の場合、電子メール、URL、UUID などの特定のチェックを考慮する必要があります。ここで、ヘルパー関数 handleStringCheck が登場します。この関数は文字列スキーマを検査し、チェックが存在する場合は、関連するモック値 (電子メールの場合は電子メール、URL の場合は URL) を返します。特定のチェックが見つからない場合、デフォルトでランダムな単語が生成されます。

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

generateMockDataFromSchema では、このヘルパーを使用して、チェック付きの文字列フィールドのデータを生成します。

数値

ZodNumber の場合、Faker の faker.number.int() メソッドを使用して整数を生成します。この部分は、スキーマで定義されている場合、最小値と最大値を処理するようにさらにカスタマイズできます。

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

ブール値

ブール値の場合、Faker は true または false の値をランダムに生成するシンプルな faker.datatype.boolean() 関数を提供します。

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

配列

ZodArray を扱うとき、配列内の各要素の模擬データを再帰的に生成します。また、options パラメータを使用して配列の長さをカスタマイズすることもできます。

配列を生成するには、まず getArrayLength を使用して長さを決定します。これは、オプションの最小長と最大長をチェックするヘルパー関数です。配列要素ごとに、generateMockDataFromSchema が再帰的に呼び出され、配列内のネストされたスキーマも確実に処理されます。

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

オプションのフィールドと Null 許容フィールド

オプションのフィールドと null 許容フィールドは、出力に含めるかどうかをランダムに決定することによって処理されます。 options.optional.probability 設定を使用すると、この確率を制御できます。フィールドが生成されると、内部スキーマに対してgenerateMockDataFromSchemaを再帰的に呼び出します。

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

ネストされたフィールドを持つオブジェクト

ZodObject の場合、各キーと値のペアを反復処理し、各フィールドのデータを再帰的に生成します。このアプローチは、深くネストされたオブジェクトをサポートし、柔軟性が高くなります。

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

使用例

generateMockDataFromSchema を配置したら、実際の動作を見てみましょう。これは、さまざまな型、オプションのフィールド、およびネストされた配列を含むスキーマの例である UserSchema です。

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

カスタマイズオプションの追加

generateMockDataFromSchema 関数は、配列の長さとオプションのフィールドの動作をカスタマイズするためのオプションのオプション パラメーターも受け入れます。これらのオプションの使用方法の例を次に示します:

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

これにより、配列フィールドの長さが 2 ~ 5 になることが保証され、オプションのフィールドが 70% の確率で生成されます。

ヘルパー関数のテスト

generateMockDataFromSchema が期待どおりに機能することを確認するには、さまざまなスキーマ構成の単体テストを作成します。以下は配列スキーマのテストの例です:

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

さまざまなスキーマ タイプと構成のテストを作成することで、さまざまなシナリオでヘルパー関数が正しく動作することを確認できます。

結論

Zod と Faker を組み合わせることで、TypeScript プロジェクトに合わせた強力で再利用可能なモック データ ジェネレーターを作成しました。さまざまなシナリオをテストし、実際のデータを実際に確認できるため、迅速な開発と品質テストに非常に役立ちます。

以上がZod と Faker を使用したモックデータ生成用の TypeScript ヘルパーの構築の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。