jestjs - 在 NestJS Jest 测试中覆盖提供程序

标签 jestjs nestjs

我想在我的 NestJS 应用程序中使用内存中的 Mongo 实例来模拟数据以进行测试。我有一个数据库提供程序,它使用 mongoose 连接到我的生产数据库,这是我的数据库模块的一部分,它又被导入到其他模块中。
我试图在我的 Jest 测试中覆盖数据库提供程序,以便可以使用内存中的 Mongo 实例。
这是数据库模块:

import { Module } from '@nestjs/common';
import { databaseProviders } from './database.providers';

@Module({
  providers: [...databaseProviders],
  exports: [...databaseProviders],
})
export class DatabaseModule { }
和数据库提供者:
export const databaseProviders = [
  {
    provide: 'DbConnectionToken',
    useFactory: async (): Promise<typeof mongoose> =>
      await mongoose.connect(PRODUCTION_DATABASE_URL),
  },
];
我有一个事件模块,它从数据库模块导入和使用数据库连接,事件服务是我正在测试的 - 我的 events.spec.ts 中的 beforeEach:
beforeEach(async () => {
    const module = await Test.createTestingModule({
      imports: [EventsModule],
      providers: [
        EventsService,
        {
          provide: 'EventModelToken',
          useValue: EventSchema
        },
      ],
    }).compile();

    eventService = module.get<EventsService>(EventsService);
  });
我尝试将 DatabaseModule 导入到测试模块中,然后添加我的自定义提供程序,假设它会覆盖数据库提供程序,但它没有按我的预期工作,所以我担心我可能会误解覆盖提供程序在这种情况下的工作方式。
这是我尝试过的:
beforeEach(async () => {
  const module = await Test.createTestingModule({
    imports: [EventsModule, DatabaseModule],
    providers: [
      EventsService,
      {
        provide: 'EventModelToken',
        useValue: EventSchema
      },
      {
        provide: 'DbConnectionToken',
        useFactory: async (): Promise<typeof mongoose> =>
          await mongoose.connect(IN_MEMORY_DB_URI),
      },
    ],
  }).compile();

  eventService = module.get<EventsService>(EventsService);
});

最佳答案

如文档 https://docs.nestjs.com/fundamentals/unit-testing 中所述您可以使用值、工厂或类覆盖提供程序。

beforeEach(async () => {
    const module = await Test.createTestingModule({
        imports: [EventsModule, DatabaseModule],
        providers: [
            EventsService,
        ],
    }).overrideProvider('DbConnectionToken')
    .useFactory({
        factory: async (): Promise<typeof mongoose> =>
          await mongoose.connect(IN_MEMORY_DB_URI),
    })
    .compile();

    eventService = module.get<EventsService>(EventsService);
});
另一种方法是为您的配置提供提供者:) 就像这样!
@Module({})
export DatabaseModule {
    public static forRoot(options: DatabaseOptions): DynamicModule {
        return {
            providers: [
                {
                    provide: 'DB_OPTIONS',
                    useValue: options,
                },
                {
                    provide: 'DbConnectionToken',
                    useFactory: async (options): Promise<typeof mongoose> => await mongoose.connect(options),
                    inject: ['DB_OPTIONS']
                },
            ],
        };
    }
}
然后像这样使用
const module: TestingModule = await Test.createTestingModule({
    imports: [DatabaseModule.forRoot({ host: 'whatever'})],
});
现在您可以在任何地方使用它来更改选项 :)

关于jestjs - 在 NestJS Jest 测试中覆盖提供程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52095261/

相关文章:

node.js - NestJS 和 TypeORM 问题有或没有 tsconfig 目标 es5

vue.js - Jest/Vue : registering components

jestjs - 如何处理项目中发现的重复的手动模拟

javascript - 手动模拟不适用于 Jest

javascript - NestJS + TypeORM - 连接到 mysql 和 mongodb 时出错

node.js - 打字机。通过日期查询时仅使用日期部分并排除时间戳部分

reactjs - 为 React Router 测试解决 React Lazy Components

typescript - 更新到 27 后,Angular jest 无法理解导入路径

graphql - NestJS 上下文在 graphql 订阅中未定义

unit-testing - 在 Nestjs 中 Jest 单元测试模拟 google oauthClient