Guide
Defining Factory

Defining a Factory

To define a factory, use .define. Each property value needs to be wrapped in a function.

import { factory } from "@factory-js/factory";
 
const userFactory = factory.define({
  props: {
    firstName: () => "John",
    lastName: () => "Doe",
    age: () => Promise.resolve(20), // Promise can also be used
  },
  vars: {},
});
 
console.log(await userFactory.build());

To generate objects using the defined factory, use .build.

const user = await userFactory.build();
console.log(user); // 👉 { "firstName": "John", "lastName": "Doe", "age": 20 }

Generating Multiple Objects

You can generate multiple objects at once using .buildList. The result will be returned as an array.

await userFactory.buildList(2); // 👉 [{ "firstName": "John", "lastName": "Doe" }, {...}]

Using Random Values

You can also make each property's value random for each build. In the example below, Faker (opens in a new tab) is used to generate random values, but you can use any library.

import { factory } from "@factory-js/factory";
import { faker } from "@faker-js/faker";
 
const userFactory = factory.define({
  props: {
    firstName: () => faker.person.firstName(),
    lastName: () => faker.person.lastName(),
  },
  vars: {},
});

If you call .build multiple times, the results will be random as shown below.

console.log(userFactory.build()); // 👉 { "firstName": "John", "lastName": "Doe" }
console.log(userFactory.build()); // 👉 { "firstName": "Tom", "lastName": "Smith" }

Saving Objects

You can also save generated objects to the database by combining them with an ORM library. You can specify how to save objects to the database by passing a function as the second argument to .define. Below is an example of saving data to the database using Prisma's create() (opens in a new tab).

import { factory } from "@factory-js/factory";
import { faker } from "@faker-js/faker";
// `db` assumes an instance of `PrismaClient`
import { db } from "../db";
 
const userFactory = factory.define(
  {
    props: {
      firstName: () => "John",
      lastName: () => "Doe",
    },
    vars: {},
  },
  async (user) => {
    return db.user.create({ data: user });
  },
);

To call the function set as the second argument, use .create instead of .build. You can also use .createList to save multiple objects at once.

await userFactory.create(); // Calls the function set as the second argument and returns the result
await userFactory.createList(2);

FactoryJS simply calls the function set as the second argument and returns the result, without depending on the specifications of any particular ORM or library. Therefore, you can combine it with libraries other than Prisma or save data to a CSV file instead of a database.

Defining Variables

To define variables, define them in the vars property. As with props, each variable value needs to be wrapped in a function.

import { factory } from "@factory-js/factory";
import { faker } from "@faker-js/faker";
 
const userFactory = factory.define({
  props: {
    firstName: () => "John",
    lastName: () => "Doe",
  },
  vars: {
    title: () => "Mr.",
    greeting: () => Promise.resolve("Hello"), // Promise can also be used
  },
});

For more details on how to use variables, refer to Variable.

Specifying Types

FactoryJS automatically infers types, so you generally don't need to specify property types explicitly. However, you can specify types explicitly using generics as shown below.

import { factory } from "@factory-js/factory";
 
type User = { firstName: string; lastName: string };
 
const userFactory = factory.define<User>({
  props: {
    firstName: () => "John",
    lastName: () => "Doe",
  },
  vars: {},
});

As a note, if a factory with explicitly specified property types uses variables or .create, you also need to specify the types for variables and .create.

import { factory } from "@factory-js/factory";
 
type User = { firstName: string; lastName: string }; // Property type
type SavedUser = { firstName: string; lastName: string; isSaved: true }; // Return type of `.create`
type Vars = { title: string }; // Variable type
 
const userFactory = factory.define<User, SavedUser, Vars>(
  {
    props: {
      firstName: () => "John",
      lastName: () => "Doe",
    },
    vars: {
      title: () => "Mr.",
    },
  },
  async (props) => {
    return { ...props, isSaved: true };
  },
);