API Packages@mockmaster/data

@mockmaster/data

Factories & Faker.js integration

npm install @mockmaster/data

Overview

The data package provides a powerful factory system for generating realistic test data using Faker.js.

Key Features:

  • Factory definitions for data models
  • Faker.js integration for realistic data
  • Sequence generation for unique IDs
  • Build single objects or lists
  • Override default values

API Reference

defineFactory(name, definition)

Define a factory for generating objects.

import { defineFactory, fake } from '@mockmaster/data'
 
const userFactory = defineFactory('user', {
  id: (ctx) => ctx.sequence('user'),
  name: () => fake.person.fullName(),
  email: () => fake.internet.email(),
  age: () => fake.number.int({ min: 18, max: 80 })
})

Parameters:

  • name (string) - Factory name
  • definition (object) - Object defining how to generate each field

Returns: Factory<T> - Factory function

build(factory, options?)

Build a single object from a factory.

import { build } from '@mockmaster/data'
 
const user = build(userFactory)
// { id: 1, name: 'John Doe', email: 'john@example.com', age: 32 }
 
// With overrides
const admin = build(userFactory, {
  overrides: {
    email: 'admin@company.com',
    role: 'admin'
  }
})

Parameters:

  • factory (Factory) - Factory to build from
  • options (object, optional) - Options with overrides

Returns: Object of type T

buildList(factory, count, options?)

Build multiple objects from a factory.

import { buildList } from '@mockmaster/data'
 
const users = buildList(userFactory, 5)
// Array of 5 users with sequential IDs
 
// With overrides
const testUsers = buildList(userFactory, 3, {
  overrides: {
    company: 'Test Corp'
  }
})

Parameters:

  • factory (Factory) - Factory to build from
  • count (number) - Number of objects to build
  • options (object, optional) - Options with overrides

Returns: Array of objects

fake

Access to all Faker.js functionality.

import { fake } from '@mockmaster/data'
 
fake.person.fullName()      // 'John Doe'
fake.internet.email()       // 'john@example.com'
fake.number.int({ min: 1, max: 100 })  // 42
fake.date.past()            // Date object

Factory Context

Factory functions receive a context object with utilities:

ctx.sequence(name)

Generate auto-incrementing sequences.

const factory = defineFactory('user', {
  id: (ctx) => ctx.sequence('user'),        // 1, 2, 3, ...
  accountId: (ctx) => `ACC-${ctx.sequence('account')}`  // ACC-1, ACC-2, ...
})

Accessing Other Fields

Access previously defined fields in the factory:

const factory = defineFactory('user', {
  firstName: () => fake.person.firstName(),
  lastName: () => fake.person.lastName(),
  email: (ctx) => {
    return `${ctx.firstName}.${ctx.lastName}@example.com`.toLowerCase()
  }
})

Faker.js Reference

Person Data

fake.person.fullName()      // 'John Doe'
fake.person.firstName()     // 'Jane'
fake.person.lastName()      // 'Smith'
fake.person.jobTitle()      // 'Software Engineer'
fake.person.sex()           // 'female'
fake.person.bio()           // Long bio text

Internet Data

fake.internet.email()        // 'john.doe@example.com'
fake.internet.userName()     // 'john_doe123'
fake.internet.password()     // 'xK9#mP2$vL5@'
fake.internet.url()          // 'https://example.com'
fake.internet.domainName()   // 'example.com'
fake.internet.ipv4()         // '192.168.1.1'
fake.internet.userAgent()    // 'Mozilla/5.0...'

Number Data

fake.number.int({ min: 1, max: 100 })      // 42
fake.number.float({ min: 0, max: 1 })      // 0.567
fake.number.int({ min: 1000, max: 9999 })  // 5432

Date Data

fake.date.past()            // Date in the past
fake.date.future()          // Date in the future
fake.date.recent()          // Recent date (last few days)
fake.date.soon()            // Soon (next few days)
fake.date.between({
  from: '2020-01-01',
  to: '2024-12-31'
})

Location Data

fake.location.city()           // 'New York'
fake.location.country()        // 'United States'
fake.location.streetAddress()  // '123 Main St'
fake.location.zipCode()        // '10001'
fake.location.latitude()       // 40.7128
fake.location.longitude()      // -74.0060

Company Data

fake.company.name()            // 'Acme Corp'
fake.company.catchPhrase()     // 'Innovative solutions'
fake.company.buzzPhrase()      // 'Synergize metrics'

Commerce Data

fake.commerce.productName()    // 'Handcrafted Steel Shoes'
fake.commerce.price()          // '49.99'
fake.commerce.department()     // 'Electronics'
fake.commerce.productDescription()  // Long description

Lorem Text

fake.lorem.word()              // 'voluptatem'
fake.lorem.words(5)            // 'voluptatem architecto...'
fake.lorem.sentence()          // 'Voluptatem architecto...'
fake.lorem.paragraph()         // Long paragraph
fake.lorem.paragraphs(3)       // 3 paragraphs

Helpers

fake.helpers.arrayElement(['a', 'b', 'c'])  // Random element
fake.helpers.arrayElements(['a', 'b', 'c', 'd'], { min: 1, max: 3 })  // Multiple elements
fake.helpers.shuffle([1, 2, 3, 4, 5])       // Shuffled array

Usage Examples

User Factory

import { defineFactory, build, buildList, fake } from '@mockmaster/data'
 
interface User {
  id: number
  name: string
  email: string
  role: 'admin' | 'user' | 'guest'
  createdAt: Date
}
 
const userFactory = defineFactory<User>('user', {
  id: (ctx) => ctx.sequence('user'),
  name: () => fake.person.fullName(),
  email: () => fake.internet.email(),
  role: () => fake.helpers.arrayElement(['admin', 'user', 'guest'] as const),
  createdAt: () => fake.date.past()
})
 
const user = build(userFactory)
const users = buildList(userFactory, 10)

Product Factory

const productFactory = defineFactory('product', {
  id: (ctx) => ctx.sequence('product'),
  name: () => fake.commerce.productName(),
  description: () => fake.commerce.productDescription(),
  price: () => parseFloat(fake.commerce.price()),
  category: () => fake.commerce.department(),
  inStock: () => fake.datatype.boolean(),
  sku: (ctx) => `SKU-${ctx.id.toString().padStart(6, '0')}`,
  createdAt: () => fake.date.past()
})

Nested Objects

const addressFactory = defineFactory('address', {
  street: () => fake.location.streetAddress(),
  city: () => fake.location.city(),
  state: () => fake.location.state(),
  zipCode: () => fake.location.zipCode()
})
 
const userFactory = defineFactory('user', {
  id: (ctx) => ctx.sequence('user'),
  name: () => fake.person.fullName(),
  address: () => build(addressFactory)
})

Dependent Fields

const userFactory = defineFactory('user', {
  firstName: () => fake.person.firstName(),
  lastName: () => fake.person.lastName(),
  email: (ctx) => {
    return `${ctx.firstName}.${ctx.lastName}@example.com`.toLowerCase()
  },
  username: (ctx) => {
    return `${ctx.firstName}_${ctx.lastName}`.toLowerCase()
  }
})

TypeScript Support

Full TypeScript support with generics:

import { defineFactory, build, type Factory } from '@mockmaster/data'
 
interface User {
  id: number
  name: string
  email: string
}
 
const userFactory: Factory<User> = defineFactory<User>('user', {
  id: (ctx) => ctx.sequence('user'),
  name: () => fake.person.fullName(),
  email: () => fake.internet.email()
})
 
// Type-safe
const user: User = build(userFactory)

Best Practices

1. Use Named Sequences

// Good
(ctx) => ctx.sequence('user')
(ctx) => ctx.sequence('product')
 
// Bad - all use same sequence
(ctx) => ctx.sequence()

2. Leverage Faker Formats

// Good - format-aware
email: () => fake.internet.email()
url: () => fake.internet.url()
date: () => fake.date.past()
 
// Avoid - manual construction
email: () => `user${Math.random()}@test.com`

3. Create Reusable Factories

// Create once, use many times
const userFactory = defineFactory('user', { ... })
 
// Use throughout tests
const user1 = build(userFactory)
const user2 = build(userFactory, { overrides: { role: 'admin' } })
const users = buildList(userFactory, 10)

4. Type Your Factories

// Good - typed
const factory = defineFactory<User>('user', { ... })
 
// Avoid - untyped
const factory = defineFactory('user', { ... })