@adrien-may/factory

中文文档
2.1.0发布于 2026/01/13ISCTypeScriptCommonJS零依赖近 30 天下载 4189

测试使工厂更容易为您的实体/模型服务.

中文使用文档
文档目录9 节
  1. 安装
  2. 使用量
  3. 工厂
  4. 子事实
  5. 顺序
  6. 懒惰属性
  7. 懒惰序列
  8. 后世代数
  9. 种子( NEW)

工厂

这个软件包通过提供为您的实体/模型创建工厂的方法,使得测试更加容易. 灵感来自 工厂男孩 ++ python 软件包和 工厂女孩 👧.

npm version

Build

codecov

License: ISC Open Source Love

您也可以查看这些项目:

安装

国家预防机制

npm install @adrien-may/factory --save-dev

雅伦

yarn add @adrien-may/factory --dev

使用量

本节简要概括了您使用此套件所能实现的目标.

工厂

声明

要申报工厂,必须提供:

  • 适配器:ObjectAdapter, TypoormAdapter, ...
  • 一个实体[可选的无打字机]:您正在构建的模型
  • 要覆盖的字段( 它们的默认值或生成它们的方法)

适配器允许您坚持您的数据 。 如果你想通过打字机将数据保存在数据库中,可以使用 TypeormAdapter 。默认适配器是 ObjectAdapter 而不坚持任何东西。 您可以创建自己的适配器, 以便按您想要的方式坚持您的数据 .

import { Factory } from '@adrien-may/factory';

// Object/Entity to create
class User {
  email: string;
  role: string;
}

// Factories
class UserFactory extends Factory<User> {
  entity = User;
  attrs = {
    email: '[email protected]',
    role: 'basic',
  };
  // By default, adapter is ObjectAdapter
}

class AdminUserFactory extends Factory<User> {
  entity = User;
  attrs = {
    email: '[email protected]',
    role: 'admin',
  };
}

// Usage
const adminFactory = new AdminUserFactory();
const admin1 = adminFactory.create();
const admins = adminFactory.createMany(5);
类型
import { Factory, TypeormFactory, TypeormAdapter } from '@adrien-may/factory';
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';

const dataSource = new DataSource({
  type: 'sqlite',
  database: ':memory:',
  ... // other typeorm options
});

@Entity()
class User {
  @PrimaryGeneratedColumn()
  id: number;

  @Column('text')
  email: string;
}

export class UserFactory extends TypeormFactory<User> {
  entity = User;
  attrs = {
    email: '[email protected]',
  };
}

// Usage
const userFactory = new UserFactory(dataSource);
const user = userFactory.create();
const users = userFactory.createMany(5);
对象和接口

您可以直接使用没有定义的实体的工厂, 并且只提供接口 .

import { ObjectFactory } from '@adrien-may/factory';

interface User {
  name: string;
}

class UserFactory extends ObjectFactory<User> {
  // No entity defined
  attrs = {
    name: 'John Doe',
  };
}

// Usage
const userFactory = new UserFactory();
const user = userFactory.create();
const users = userFactory.createMany(5);
自定义

你可能想用工厂 和其他ORM或CMS。 为了说明这一点,我们将展示 你将如何建立一个工厂 有效载荷cms

为此,您应该首先创建一个适配器.

import { Adapter } from '@teammay/factory'
import {
  DataFromCollectionSlug,
  RequiredDataFromCollectionSlug,
} from 'node_modules/payload/dist/collections/config/types'

interface PayloadArgs {
  draft: boolean;
  locale: string
}

class PayloadAdapter extends Adapter<S extends CollectionSlug, [PayloadArgs?]> {
    constructor(
    private payload: Payload,
    private slug: S,
  ) {}

  async save(
    instance: RequiredDataFromCollectionSlug<S> | RequiredDataFromCollectionSlug<S>[],
    { draft = false, locale = 'en' }: PayloadArgs = { draft: false, locale: 'en' },
  ): Promise<DataFromCollectionSlug<S> | DataFromCollectionSlug<S>[]> {
    const instances = Array.isArray(instance) ? instance : [instance]
    const savedInstances = await Promise.all(
      instances.map((data) =>
        this.payload.create({
          collection: this.slug,
          data,
          draft,
          locale,
        }),
      ),
    )
    return Array.isArray(instance) ? savedInstances : savedInstances[0]
  }

}

现在有了这个适配器,我们就能创造出一个"有效载荷"

import { Factory } from '@teammay/factory'
import {
  DataFromCollectionSlug,
  RequiredDataFromCollectionSlug,
} from 'node_modules/payload/dist/collections/config/types'
import { CollectionSlug, Payload } from 'payload'



abstract class PayloadFactory<S extends CollectionSlug> extends Factory<DataFromCollectionSlug<S>, [PayloadArgs?]> {
  constructor(protected payload: Payload, protected slug: S) {
    super()
    this.adapter = new PayloadAdapter(payload, slug)
  }
}

有了这门课,我们现在可以 即兴制造工厂的每一个有效载荷收集。 例如, 如果我们有一个带有 swit'author' 的集合, 并且只包含一个字段“ 名字 ” , 我们就会这样做 :


interface User {
  name: string;
}

class UserFactory extends PayloadFactory<'author'> {
  // No entity defined
  attrs = {
    name: 'John Doe',
  };
}

// Usage
const userFactory = new UserFactory();
const user = userFactory.create({}, {draft: true, locale: 'fr'});
const users = userFactory.createMany(5, {}, {draft: false, locale: 'es'});

带有Fakerjs/Chancejs/的模糊生成

为了为工厂生成伪随机数据,我们可以利用图书馆:

import { TypeormFactory } from '@adrien-may/factory';
import Chance from 'chance';

const chance = new Chance();

export class ProfileFactory extends TypeormFactory<Profile> {
  entity = Profile;
  attrs = {
    name: () => chance.name(),
    email: () => chance.email(),
    description: () => chance.paragraph({ sentences: 5 }),
  };
}

注:Faker/Change不在本库. 我们只利用一个函数传递给 attrs 每次创建工厂都叫它 因此,您可以使用Faker/Chancejs生成数据.

利用我们创造的工厂

我们可以利用我们的工厂创造新的实体实例:

const userFactory = new UserFactory();

对于打字机工厂,您应当使用下列方法设置默认工厂:

import { setDefaultFactory } from '@adrien-may/factory';
{...}
setDefaultDataSource(typeormDatasource)
{...}
const userFactory = new UserFactory();

或者为每个实例设置数据源,使用:

const userFactory = new UserFactory(typeormDatasource);

工厂及其适配器暴露出一些功能:

  • 构建:创建对象(并最终生成数据/子事实)
  • 创建: 通过 ORM "保存" 方法在数据库中与 make 相同但持久性对象
  • 建立 Many 和 Create Many 允许在一次中创建多个实例
const user: User = await userFactory.create();
const users: User[] = await userFactory.createMany(5);

要覆盖工厂默认属性, 请将它们添加为创建函数的参数 :

const user: User = await userFactory.create({ email: '[email protected]' });

子事实

实体之间(许多ToOne,一个ToOny,一个TOOne等)有关系是很常见的. 在这种情况下,我们为所有实体创建工厂,并利用 SubFactory 在他们之间建立联系。 子事实将在建立实例时解决 。 注意,这是纯粹的合成糖,因为人们可以使用一个叫另一个工厂的箭头函数.

示例

如果一个用户有一个配置实体与之链接:我们使用 UserFactory 作为子事实 ProfileFactory

import { Factory, SubFactory } from '@adrien-may/factory';
import { UseFactory } from './user.factory.ts'; // factory naming is free of convention here, don't worry about it.

export class ProfileFactory extends Factory<Profile> {
  entity = Profile;
  attrs = {
    name: 'Handsome name',
    user: new SubFactory(UserFactory, { name: 'Override factory name' }),
  };
}

顺序

序列允许你得到一个递增值 每次运行在同一工厂. 这样,你可以使用一个计数器来获得更有意义的数据.

import { Factory, Sequence } from '@adrien-may/factory';

export class UserFactory extends Factory<User> {
  entity = User;
  attrs = {
    customerId: new Sequence((nb: number) => `cust__abc__xyz__00${nb}`),
  };
}

懒惰属性

懒惰属性在您想要根据正在创建的实例生成值时有用 . 它们按其他属性解决,但在拯救实体之前解决。 对于任何动作"后保存",使用后Generate钩.

import { Factory, LazyAttribute } from '@adrien-may/factory';

export class UserFactory extends Factory<User> {
  entity = User;
  attrs = {
    name: 'Sarah Connor',
    mail: new LazyAttribute(instance => `${instance.name.toLowerCase()}@skynet.org`),
  };
}

懒惰序列

懒惰的序列结合了序列和懒惰属性的力量. 调用时使用递增数并创建实例.

import { Factory, LazySequence } from '@adrien-may/factory';

export class UserFactory extends Factory<User> {
  entity = User;
  attrs = {
    name: 'Sarah Connor',
    mail: new LazySequence((nb, instance) => `${instance.name.toLowerCase()}.${nb}@skynet.org`),
  };
}

后世代数

要在创建实例后执行动作, 您可以使用 PostGeneration 装饰师.

import { Factory, PostGeneration } from '@adrien-may/factory';

export class UserFactory extends Factory<User> {
  ...

  @PostGeneration()
  postGenerationFunction() {
    // perform an action after creation
  }

  @PostGeneration()
  async actionOnCreatedUser(user: User) {
    // do something with user
  }
}

适配器

您可以提供自己的适配器来扩展此库. 这个图书馆现在提供 ObjectAdapter (违约)和 TypeormAdapter 。 。 。 . 为方便测试,此库提供 TypeormFactory 课.

以下例子说明如何使用这些工具:

import { Factory, TypeormFactory, TypeormAdapter } from '@adrien-may/factory';

export class UserFactory extends Factory<User> {
  entity = User;
  attrs = {
    email: '[email protected]',
    role: 'basic',
  };
  adapter = TypeormAdapter();
}

// Same as:
export class TypeormUserFactory extends TypeormFactory<User> {
  entity = User;
  attrs = {
    email: '[email protected]',
    role: 'admin',
  };
}

种子( NEW)

你现在可以很容易地在你的数据库里 使用你的工厂 runSeed 函数.

示例

创建一个 seed.ts 在工程中的文件 :

import { runSeed } from '@adrien-may/factory';
import { UserFactory } from './factories/user.factory';
import { PostFactory } from './factories/post.factory';
import { dataSource } from './db'; // your TypeORM DataSource

export let fixtures: any = {};

async function main() {
  fixtures = await runSeed({
    dataSource,
    factories: { UserFactory, PostFactory },
    seeds: async ({ UserFactory, PostFactory }) => {
      const users = await UserFactory.createMany(10);
      const posts = await PostFactory.createMany(20);
      return {
        users,
        posts,
      };
    },
  });
}

main();
  • 所有工厂都与提供 dataSource。 。 。 .
  • 您可以使用所有厂房方法( 创建、 创建 Many等) seeds 函数.
  • 这种功能具有框架不可知性,但与TypeORM最有效.
  • 您可以通过 fixtures 对象.

示例: 在 Jest 设置中种子

您还可以使用 runSeed 在您的 Jest 设置中确保测试数据库在测试运行前被种子 :

// jest.setup.ts
import { runSeed } from '@adrien-may/factory';
import { UserFactory } from './factories/user.factory';
import { dataSource } from './db';

beforeAll(async () => {
  await runSeed({
    dataSource,
    factories: { UserFactory },
    seeds: async ({ UserFactory }) => {
      await UserFactory.createMany(5);
    },
  });
});

示例:通过 npm 运行种子

将此添加到您的 package.json 脚本 :

"scripts": {
  "seed": "ts-node ./seed.ts"
}

然后运行 :

npm run seed

版本与发布记录

@adrien-may/factory 共发布 15 个版本,首次发布于 2022/01/13;过去 12 个月发布了 3 个版本。

版本发布日期距今
2.1.0latest2026/01/139 个月前
2.0.42025/11/2711 个月前
2.0.32025/11/2711 个月前
2.0.22025/11/061 年前
2.0.12025/11/031 年前
2.0.02025/11/031 年前

关于 @adrien-may/factory 的常见问题

@adrien-may/factory 是什么?

测试使工厂更容易为您的实体/模型服务.

如何安装 @adrien-may/factory?

在项目目录运行 npm install @adrien-may/factory,或使用 pnpm add / yarn add / bun add。

@adrien-may/factory 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@adrien-may/factory 支持 ESM 还是 CommonJS?

以 CommonJS 形式发布,可以直接 require();在 ES Module 项目中也可以用 import 引入(Node.js 会把 module.exports 作为默认导出)。

@adrien-may/factory 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=24。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@adrien-may/factory 可以商用吗?

@adrien-may/factory 使用 ISC 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@adrien-may/factory 的下载量有多少?

根据 npm 官方下载统计,@adrien-may/factory 在 2026/10/05 – 2026/11/03 这 30 天内被下载 4,189 次,日均约 140 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@adrien-may/factory 还在维护吗?

最新版本 2.1.0 发布于 2026/01/13(9 个月前);至今共发布 15 个版本,其中过去 12 个月发布了 3 个;首次发布于 2022/01/13。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。