テストデータ、毎回手入力していませんか?
TypeScript/JavaScriptでテストコードを書く時、こんな経験ありませんか?
- 「テスト用のユーザーデータ、また”test@example.com”を使い回してしまった…」
- 「DBシードで100件のサンプルデータが必要だけど、手で書くのは無理」
- 「テストの度に同じデータだと、エッジケースを見逃しそう」
そんな時に役立つのがFaker.js(@faker-js/faker)です。名前、メールアドレス、住所、日付など、リアルなダミーデータを簡単に生成できるJavaScriptライブラリです。
この記事では、Faker.jsの基本的な使い方から実践的な活用例まで、開発現場ですぐに使えるテクニックを紹介します。
Faker.jsって何?なぜ使うの?
Faker.jsは、テスト・開発用のダミーデータを自動生成するライブラリです。もともとPHPのFakerライブラリを参考に作られたため、LaravelのFakerを使ったことがある方なら馴染みやすいAPIになっています。
主な用途
- テストコード:毎回異なるデータでテストを実行できる
- DBシード:開発環境やステージング環境に大量のサンプルデータを投入
- モックデータ:APIのレスポンスモックやStorybook用データ
- デモ環境:本番に近い見た目のデータでプレゼンテーション
手動でダミーデータを作ると、"test1@example.com"、"test2@example.com"のような機械的なデータになりがちです。Faker.jsならリアルな名前・メールアドレス・住所などを自動生成してくれるので、本番環境に近い状態でテストできます。
Faker.jsのインストールと基本的な使い方
インストール
npmまたはyarnでインストールできます。
npm install @faker-js/faker --save-devまたは
yarn add @faker-js/faker -D--save-dev(-D)オプションを付けるのがポイントです。Faker.jsは開発・テスト環境でのみ使用するため、本番環境にインストールする必要はありません。
基本的な使い方
まずはシンプルなユーザーデータを生成してみましょう。
import { faker } from '@faker-js/faker';
const user = {
id: faker.string.uuid(),
name: faker.person.fullName(),
email: faker.internet.email(),
avatar: faker.image.avatar(),
createdAt: faker.date.past(),
};
console.log(user);
// 出力例:
// {
// id: '3f4e7c8a-9b2d-4f1e-a6c8-d9e4f1a2b3c4',
// name: 'John Doe',
// email: 'john.doe@example.com',
// avatar: 'https://avatars.githubusercontent.com/u/12345',
// createdAt: 2023-08-15T10:30:00.000Z
// }実行するたびに異なるデータが生成されます。このランダム性が、テストの信頼性を高める重要なポイントです。
日本語ロケール対応で日本人名や日本の住所を生成
Faker.jsは日本語ロケールにも対応しています。fakerJAをインポートすれば、日本人名や日本の都市名を生成できます。
import { fakerJA as faker } from '@faker-js/faker';
console.log(faker.person.fullName()); // 例: "山田 太郎"
console.log(faker.location.city()); // 例: "横浜市"
console.log(faker.location.state()); // 例: "神奈川県"
console.log(faker.phone.number()); // 例: "090-1234-5678"日本向けのアプリケーション開発では、fakerJAを使うことで本番環境に近いテストデータが作れます。海外ユーザー向けなら通常のfaker、国内向けならfakerJAと使い分けましょう。
よく使うカテゴリとAPI一覧
Faker.jsは多数のカテゴリに分かれています。実務でよく使うものを厳選して紹介します。
| カテゴリ | 主な用途 | 代表的なAPI |
|---|---|---|
faker.person |
人物情報 | fullName(), firstName(), lastName(), gender() |
faker.internet |
ネット関連 | email(), url(), ip(), userName() |
faker.location |
住所・地理 | city(), country(), zipCode(), latitude() |
faker.date |
日付 | past(), future(), recent(), between() |
faker.number |
数値 | int(), float(), bigInt() |
faker.lorem |
ダミーテキスト | paragraph(), sentence(), words() |
faker.image |
画像URL | avatar(), url(), urlLoremFlickr() |
faker.commerce |
商品情報 | productName(), price(), department() |
実践例:ブログ記事データの生成
import { faker } from '@faker-js/faker';
const blogPost = {
id: faker.string.uuid(),
title: faker.lorem.sentence(),
content: faker.lorem.paragraphs(3),
author: faker.person.fullName(),
publishedAt: faker.date.past(),
tags: faker.helpers.arrayElements([
'TypeScript', 'React', 'Next.js', 'Testing', 'DevOps'
], 3),
likes: faker.number.int({ min: 0, max: 1000 }),
};
console.log(blogPost);faker.helpers.arrayElements()を使えば、配列からランダムに要素を選択できます。タグやカテゴリなど、選択肢が限られているデータを生成する時に便利です。
テストコードでの活用例
Faker.jsの真価はテストコードで発揮されます。毎回異なるデータでテストすることで、特定のデータに依存したバグを発見できます。
Jestでのユニットテスト例
import { faker } from '@faker-js/faker';
import { createUser } from './userService';
describe('createUser', () => {
it('should create a user with valid data', async () => {
// 毎回異なるテストデータを生成
const userData = {
name: faker.person.fullName(),
email: faker.internet.email(),
age: faker.number.int({ min: 18, max: 99 }),
};
const result = await createUser(userData);
expect(result).toBeTruthy();
expect(result.email).toBe(userData.email);
});
it('should handle edge cases with special characters', async () => {
const userData = {
name: faker.person.fullName() + '!@#$%', // 特殊文字を含む
email: faker.internet.email(),
age: faker.number.int({ min: 18, max: 99 }),
};
const result = await createUser(userData);
// 特殊文字が適切にエスケープされているか確認
expect(result.name).toBeDefined();
});
});このように、ランダムなデータでテストを繰り返すことで、「たまたま動いている」実装を見逃しにくくなります。
シード値を固定してテストを再現可能にする
ランダムデータは便利ですが、テスト失敗時に同じデータで再現したい場合もあります。そんな時はシード値を固定しましょう。
import { faker } from '@faker-js/faker';
// シード値を固定すると、毎回同じデータが生成される
faker.seed(123);
console.log(faker.person.fullName()); // 常に同じ名前が生成される
console.log(faker.internet.email()); // 常に同じメールアドレスが生成されるCI/CD環境で再現性のあるテストを実行したい時に便利です。通常はfaker.seed()を使わず、デバッグ時のみ固定するのが良いでしょう。
DBシード(初期データ投入)での活用例
開発環境やステージング環境に大量のサンプルデータを投入する時、Faker.jsは非常に強力です。
Prismaでのシード例
// prisma/seed.ts
import { PrismaClient } from '@prisma/client';
import { faker } from '@faker-js/faker';
const prisma = new PrismaClient();
async function main() {
// 100件のユーザーデータを投入
for (let i = 0; i < 100; i++) {
await prisma.user.create({
data: {
name: faker.person.fullName(),
email: faker.internet.email(),
age: faker.number.int({ min: 18, max: 70 }),
createdAt: faker.date.past({ years: 2 }),
},
});
}
console.log('Seed data inserted successfully');
}
main()
.catch((e) => {
console.error(e);
process.exit(1);
})
.finally(async () => {
await prisma.$disconnect();
});実行コマンド:
npx prisma db seedこれで本番に近いデータ量でパフォーマンステストを実施できます。
リレーションを含む複雑なデータの生成
// ユーザーと投稿のリレーションを含むシード
async function seedUsersWithPosts() {
for (let i = 0; i < 20; i++) {
const user = await prisma.user.create({
data: {
name: faker.person.fullName(),
email: faker.internet.email(),
posts: {
create: Array.from({ length: faker.number.int({ min: 1, max: 10 }) }).map(() => ({
title: faker.lorem.sentence(),
content: faker.lorem.paragraphs(3),
publishedAt: faker.date.past(),
})),
},
},
});
console.log(`Created user: ${user.name} with posts`);
}
}ユーザーごとにランダムな数の投稿を生成することで、リアルなデータ分布をシミュレートできます。
Storybookやモックサーバーでの活用
Faker.jsはフロントエンド開発のモックデータ生成にも最適です。
Storybook用のモックデータ
// UserCard.stories.tsx
import { faker } from '@faker-js/faker';
import { UserCard } from './UserCard';
export default {
title: 'Components/UserCard',
component: UserCard,
};
// ランダムなユーザーデータでStorybookに表示
export const Default = {
args: {
user: {
name: faker.person.fullName(),
email: faker.internet.email(),
avatar: faker.image.avatar(),
bio: faker.lorem.sentence(),
},
},
};
// 複数ユーザーのリスト表示
export const UserList = {
args: {
users: Array.from({ length: 10 }).map(() => ({
name: faker.person.fullName(),
email: faker.internet.email(),
avatar: faker.image.avatar(),
})),
},
};MSW(Mock Service Worker)との組み合わせ
// mocks/handlers.ts
import { http, HttpResponse } from 'msw';
import { faker } from '@faker-js/faker';
export const handlers = [
http.get('/api/users', () => {
// APIレスポンスをFaker.jsで生成
const users = Array.from({ length: 20 }).map(() => ({
id: faker.string.uuid(),
name: faker.person.fullName(),
email: faker.internet.email(),
avatar: faker.image.avatar(),
}));
return HttpResponse.json(users);
}),
http.get('/api/users/:id', ({ params }) => {
return HttpResponse.json({
id: params.id,
name: faker.person.fullName(),
email: faker.internet.email(),
createdAt: faker.date.past(),
});
}),
];バックエンドAPIの開発が完了していなくても、フロントエンド開発を先行して進められます。
実務で役立つFaker.jsのテクニック集
カスタムロケールの作成
日本語ロケールに含まれていないデータが必要な場合、カスタムロケールを定義できます。
import { faker } from '@faker-js/faker';
// 独自のデータセットを定義
const customDepartments = ['営業部', '開発部', '人事部', '経理部', 'マーケティング部'];
function generateEmployee() {
return {
name: faker.person.fullName(),
department: faker.helpers.arrayElement(customDepartments),
employeeId: faker.string.alphanumeric(8).toUpperCase(),
hireDate: faker.date.past({ years: 10 }),
};
}
console.log(generateEmployee());範囲指定で現実的なデータを生成
import { faker } from '@faker-js/faker';
// 価格は100円〜10,000円の範囲で生成
const product = {
name: faker.commerce.productName(),
price: faker.number.int({ min: 100, max: 10000 }),
stock: faker.number.int({ min: 0, max: 500 }),
rating: faker.number.float({ min: 1, max: 5, precision: 0.1 }),
};
console.log(product);範囲指定することで、ビジネスロジックに沿った現実的なテストデータを作成できます。
重複しないデータの生成
メールアドレスなど、ユニーク制約があるデータはSetを使って重複を回避します。
import { faker } from '@faker-js/faker';
function generateUniqueEmails(count: number): string[] {
const emails = new Set<string>();
while (emails.size < count) {
emails.add(faker.internet.email());
}
return Array.from(emails);
}
const uniqueEmails = generateUniqueEmails(100);
console.log(uniqueEmails.length); // 100Laravel Fakerとの違いと使い分け
Faker.jsはPHPのFakerライブラリを参考に作られたため、Laravel Fakerと似たAPIを持っています。Laravel経験者なら違和感なく使えるでしょう。
APIの対応表
| Laravel Faker(PHP) | Faker.js(JavaScript) |
|---|---|
$faker->name |
faker.person.fullName() |
$faker->email |
faker.internet.email() |
$faker->address |
faker.location.streetAddress() |
$faker->dateTimeBetween() |
faker.date.between() |
$faker->randomElement() |
faker.helpers.arrayElement() |
Laravel Fakerに慣れている方は、カテゴリ名(person, internet, location)に注意すれば、すぐにFaker.jsを使いこなせます。
注意点とベストプラクティス
本番環境に含めない
Faker.jsはあくまで開発・テスト用のライブラリです。インストール時は必ず--save-dev(-D)オプションを付け、本番バンドルに含まれないようにしましょう。
npm install @faker-js/faker --save-dev万が一本番環境に含まれてしまうと、不要なバンドルサイズの増加につながります。ESLintなどでimportを制限するルールを設けるのも有効です。
テストの再現性を意識する
ランダムデータは強力ですが、テストが失敗した際に「どのデータで失敗したか」が分かりにくくなる場合があります。生成したデータをログに残しておくと原因調査がスムーズです。
const userData = {
name: faker.person.fullName(),
email: faker.internet.email(),
};
console.log("Test data:", userData); // 失敗時の調査用
const result = await createUser(userData);
expect(result.email).toBe(userData.email);問題が再現しない場合は、faker.seed()でシード値を固定することで同じデータを再生成できます。
バリデーションロジックに合わせたデータを生成する
Faker.jsが生成するデータは必ずしもアプリのバリデーションルールを満たすとは限りません。たとえばパスワードに文字数制限がある場合は、範囲を指定して生成しましょう。
const password = faker.internet.password({ length: 12, memorable: false });独自のバリデーションがある場合は、生成後に加工するか、faker.helpers.arrayElement()で事前に定義した有効な値から選択する方法が安全です。
大量データ生成時はパフォーマンスに注意
DBシードで数万件のデータを一件ずつawaitで挿入すると非常に時間がかかります。PrismaであればcreateMany()を活用しましょう。
const users = Array.from({ length: 1000 }).map(() => ({
name: faker.person.fullName(),
email: faker.internet.email(),
age: faker.number.int({ min: 18, max: 70 }),
}));
await prisma.user.createMany({ data: users });これにより、1件ずつ挿入する場合と比べて大幅に高速化できます。
まとめ
Faker.jsを使うことで、テスト・開発現場でのダミーデータ生成が格段に楽になります。この記事で紹介したポイントを改めて整理します。
- インストールは
--save-devで開発環境のみに限定する - 日本語ロケール(
fakerJA)を使えば国内向けアプリのテストデータも充実 - テストコードでの活用でランダムデータによる網羅性の高いテストが実現できる
- シード値の固定でテストの再現性を確保できる
- DBシードやMSW・Storybookとの組み合わせでフロントエンド・バックエンドを問わず活躍する
- 本番環境への混入や大量データ時のパフォーマンスに注意する
「またtest@example.comを使ってしまった…」と思ったら、ぜひFaker.jsを導入してみてください。テストの品質と開発効率が一気に向上するはずです。
