Faker.js Testing Guide: Generate Realistic Test Data in JavaScript

Faker.js Testing Guide: Generate Realistic Test Data in JavaScript

Faker.js generates realistic fake data for your tests: names, emails, addresses, phone numbers, dates, UUIDs, credit card numbers, and hundreds of other types. Instead of hardcoding test@example.com and John Doe everywhere, you get unique, realistic values every time.

This guide covers Faker.js from installation through advanced usage patterns.

Installation

npm install --save-dev @faker-js/faker

The current official package is @faker-js/faker. The original faker package was famously deleted in 2022 — always use the @faker-js/faker fork.

Basic Usage

const { faker } = require('@faker-js/faker');

// Person
faker.person.fullName()         // 'Johnathan Wuckert'
faker.person.firstName()        // 'Elena'
faker.person.lastName()         // 'Bernhard'
faker.person.jobTitle()         // 'Senior Solutions Consultant'

// Internet
faker.internet.email()          // 'janelle_ryan@yahoo.com'
faker.internet.userName()       // 'myles_hane74'
faker.internet.url()            // 'https://sandy-strategy.biz'
faker.internet.ipv4()           // '198.94.47.252'

// Location
faker.location.city()           // 'Port Hector'
faker.location.country()        // 'France'
faker.location.streetAddress()  // '589 Gusikowski Loop'
faker.location.zipCode()        // '35457'

// Numbers and IDs
faker.string.uuid()             // '2dc5de04-ce20-4d9c-873b-b2bb9e6b77e0'
faker.number.int({ min: 1, max: 100 })   // 42
faker.number.float({ min: 0, max: 1, precision: 0.01 })  // 0.73

// Dates
faker.date.past()               // Date object, some time in the past
faker.date.between({ from: '2023-01-01', to: '2024-01-01' })
faker.date.recent({ days: 7 })  // Last 7 days

Using Faker in Test Factories

The most common use of Faker.js is inside factory functions — functions that create test objects with sensible defaults.

const { faker } = require('@faker-js/faker');

function createUser(overrides = {}) {
  return {
    id: faker.string.uuid(),
    email: faker.internet.email(),
    name: faker.person.fullName(),
    phone: faker.phone.number(),
    role: 'user',
    createdAt: faker.date.past(),
    isActive: true,
    ...overrides,
  };
}

function createProduct(overrides = {}) {
  return {
    id: faker.string.uuid(),
    name: faker.commerce.productName(),
    description: faker.commerce.productDescription(),
    price: parseFloat(faker.commerce.price({ min: 1, max: 500 })),
    sku: faker.string.alphanumeric(10).toUpperCase(),
    stock: faker.number.int({ min: 0, max: 1000 }),
    category: faker.commerce.department(),
    ...overrides,
  };
}

Tests use these factories and only specify what they care about:

test('users with the admin role can access the dashboard', () => {
  const admin = createUser({ role: 'admin' });
  expect(canAccessDashboard(admin)).toBe(true);
});

test('products with zero stock are out of stock', () => {
  const product = createProduct({ stock: 0 });
  expect(product.isOutOfStock).toBe(true);
});

Seeding for Reproducibility

By default, Faker generates different values every run. This is usually what you want — but sometimes a test fails and you need to reproduce the exact values.

Faker supports seeding: set a seed number and you always get the same values.

// Reproducible values
faker.seed(12345);
faker.person.fullName() // Always 'Leroy Jenkins' with seed 12345
faker.internet.email()  // Always the same email with seed 12345

// Back to random
faker.seed(); // or faker.seed(Date.now())

Seeding Strategy in CI

Log the seed at test start, and on failure you can reproduce it:

// jest.setup.js
const seed = process.env.FAKER_SEED 
  ? parseInt(process.env.FAKER_SEED) 
  : Date.now();

faker.seed(seed);
console.log(`Faker seed: ${seed}`);

To reproduce a failure:

FAKER_SEED=1706789234567 npm test

Locales

Faker supports 60+ locales. Use this when your app is locale-specific or when you need realistic non-English data.

const { fakerDE, fakerJA, fakerPT_BR } = require('@faker-js/faker');

// German data
fakerDE.person.fullName()    // 'Heinz Müller'
fakerDE.location.city()      // 'München'

// Japanese data
fakerJA.person.fullName()    // '田中 太郎'
fakerJA.location.city()      // '大阪市'

// Brazilian Portuguese
fakerPT_BR.person.firstName()  // 'João'
fakerPT_BR.location.state()    // 'São Paulo'

Or configure locale on a specific instance:

const { Faker, de } = require('@faker-js/faker');
const fakerDe = new Faker({ locale: [de] });

Available Data Categories

Faker.js has 14 top-level modules. Here are the most useful for testing:

Commerce

faker.commerce.productName()          // 'Ergonomic Wooden Table'
faker.commerce.productDescription()   // 'The Nagasaki Lander is...'
faker.commerce.price({ min: 1, max: 500, dec: 2 })  // '149.99'
faker.commerce.department()           // 'Electronics'
faker.commerce.productAdjective()     // 'Refined'
faker.commerce.productMaterial()      // 'Concrete'

Finance

faker.finance.accountNumber()         // '84063934'
faker.finance.amount()                // '871.90'
faker.finance.currency()              // { code: 'EUR', name: 'Euro', symbol: '€' }
faker.finance.creditCardNumber()      // '4111111111111111'
faker.finance.iban()                  // 'DE89370400440532013000'
faker.finance.transactionType()       // 'payment'

Company

faker.company.name()          // 'Sipes, Kirlin and Sons'
faker.company.buzzNoun()       // 'paradigm'
faker.company.catchPhrase()    // 'Robust mission-critical toolset'
faker.company.buzzPhrase()     // 'scale agile interfaces'

System

faker.system.fileName()       // 'config.json'
faker.system.filePath()       // '/usr/local/var/config.json'
faker.system.mimeType()       // 'image/png'
faker.system.fileExt()        // 'mp4'
faker.system.semver()         // '1.14.2'

Lorem

faker.lorem.word()            // 'consequatur'
faker.lorem.sentence()        // 'Deserunt est officia...'
faker.lorem.paragraph()       // Full paragraph
faker.lorem.lines(3)          // 3 lines of lorem text
faker.lorem.words(5)          // 'voluptas omnis quos eos reprehenderit'

Unique Values

When you need guaranteed-unique values across a test run:

const { faker } = require('@faker-js/faker');

// Using the unique helper (deprecated in v9 — use other strategies)
// faker.unique(faker.internet.email)

// Better: use UUIDs for IDs
faker.string.uuid() // Guaranteed globally unique

// Or use a counter
let counter = 0;
const uniqueEmail = () => `user-${++counter}@example.com`;

// Or use faker.helpers.unique for custom generators
const unique = faker.helpers.unique(faker.internet.email);

Custom Data with Faker Helpers

Picking from Arrays

const roles = ['admin', 'editor', 'viewer'];
faker.helpers.arrayElement(roles)    // picks one
faker.helpers.arrayElements(roles, 2) // picks 2

const permissions = faker.helpers.shuffle(['read', 'write', 'delete']);

Weighted Random

faker.helpers.weightedArrayElement([
  { weight: 10, value: 'user' },
  { weight: 3, value: 'editor' },
  { weight: 1, value: 'admin' },
])
// Returns 'user' ~71% of the time

fromRegExp

Generate strings matching a pattern:

faker.helpers.fromRegExp(/[A-Z]{2}[0-9]{4}/)   // 'AB1234'
faker.helpers.fromRegExp('[0-9]{3}-[0-9]{4}')   // '555-1234'

mustache

Fill in templates:

faker.helpers.mustache(
  'Hello {{name}}, your order {{orderId}} is ready.',
  {
    name: faker.person.firstName,
    orderId: () => faker.string.alphanumeric(8).toUpperCase(),
  }
)
// 'Hello Sarah, your order AB12CD34 is ready.'

Building a Test Data Layer

For larger codebases, centralize all faker usage in a test/factories directory:

test/
  factories/
    user.factory.js
    order.factory.js
    product.factory.js
  helpers/
    db.js
  setup.js
// test/factories/user.factory.js
const { faker } = require('@faker-js/faker');
const db = require('../helpers/db');

const UserFactory = {
  // In-memory only (for unit tests)
  build: (overrides = {}) => ({
    id: faker.string.uuid(),
    email: faker.internet.email(),
    name: faker.person.fullName(),
    role: 'user',
    isActive: true,
    createdAt: new Date(),
    ...overrides,
  }),

  // Persisted (for integration tests)
  create: async (overrides = {}) => {
    const data = UserFactory.build(overrides);
    const [user] = await db.query(
      'INSERT INTO users (id, email, name, role, is_active, created_at) VALUES ($1, $2, $3, $4, $5, $6) RETURNING *',
      [data.id, data.email, data.name, data.role, data.isActive, data.createdAt]
    );
    return user;
  },

  createMany: (n, overrides = {}) =>
    Promise.all(Array.from({ length: n }, () => UserFactory.create(overrides))),
};

module.exports = UserFactory;

Usage:

const UserFactory = require('../factories/user.factory');

// Unit test
const user = UserFactory.build({ role: 'admin' });

// Integration test
const user = await UserFactory.create({ role: 'admin' });
const users = await UserFactory.createMany(5, { role: 'viewer' });

What NOT to Use Faker For

Assertion values

// Wrong — assertion will always fail
const user = UserFactory.build();
expect(user.email).toBe('specific@example.com');

// Right — if you're asserting a specific value, specify it
const user = UserFactory.build({ email: 'specific@example.com' });
expect(user.email).toBe('specific@example.com');

Enum fields you're branching on

// Risky — test result depends on which role Faker generates
const user = UserFactory.build();
if (user.role === 'admin') {
  // This branch is only hit sometimes
}

// Right — be explicit
const admin = UserFactory.build({ role: 'admin' });
const regularUser = UserFactory.build({ role: 'user' });

Dates with business logic

// Risky — faker.date.past() could generate a date that's 5 years ago
// or yesterday, and your logic might only look back 30 days
const user = UserFactory.build({ createdAt: faker.date.past() });

// Right — be specific about date ranges
const recentUser = UserFactory.build({
  createdAt: faker.date.recent({ days: 7 }),
});
const oldUser = UserFactory.build({
  createdAt: faker.date.past({ years: 2 }),
});

Faker.js vs. Alternatives

Library Language Notes
@faker-js/faker JavaScript/TypeScript Most comprehensive JS faker, active community
Chance.js JavaScript Smaller API, good for simple use cases
Rosie JavaScript Factory library, works well alongside faker
Fishery TypeScript TypeScript-first factories, excellent type safety
Faker (Python) Python Port of Faker.js concepts to Python
factory_boy Python Django-native factories
Bogus C# .NET port

Summary

Faker.js is most valuable when you pair it with the factory pattern:

  1. Factories define the shape of your test objects
  2. Faker populates fields that tests don't care about with realistic values
  3. Tests only specify the fields that drive the behavior under test

The result: tests that are readable, isolated, and resilient to schema changes — because "email" in a test now means "some valid email", not "this specific hardcoded string that will collide with the next parallel test run".

Read more