Jestjs 在NestJS Jest测试中重写提供程序

Jestjs 在NestJS Jest测试中重写提供程序,jestjs,nestjs,Jestjs,Nestjs,我想在我的NestJS应用程序中使用内存中的Mongo实例模拟数据以进行测试。我有一个数据库提供程序,它使用mongoose连接到我的生产数据库,mongoose是我的数据库模块的一部分,然后被导入到其他模块中 我试图在Jest测试中重写数据库提供程序,以便可以使用内存中的Mongo实例 这是数据库模块: import { Module } from '@nestjs/common'; import { databaseProviders } from './database.providers

我想在我的NestJS应用程序中使用内存中的Mongo实例模拟数据以进行测试。我有一个数据库提供程序,它使用mongoose连接到我的生产数据库,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),
  },
];
导出常量数据库提供程序=[
{
提供:“DbConnectionToken”,
useFactory:async():Promise=>
等待mongoose.connect(生产数据库URL),
},
];
我有一个事件模块,它从数据库模块导入并使用数据库连接。事件服务是我正在测试的-在我的Events.spec.ts中的beforeach:

beforeEach(async () => {
    const module = await Test.createTestingModule({
      imports: [EventsModule],
      providers: [
        EventsService,
        {
          provide: 'EventModelToken',
          useValue: EventSchema
        },
      ],
    }).compile();

    eventService = module.get<EventsService>(EventsService);
  });
beforeach(异步()=>{
const module=await Test.createTestingModule({
导入:[EventsModule],
供应商:[
事件服务,
{
提供:“EventModelToken”,
useValue:EventSchema
},
],
}).compile();
eventService=module.get(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);
});
beforeach(异步()=>{
const module=await Test.createTestingModule({
导入:[EventsModule,DatabaseModule],
供应商:[
事件服务,
{
提供:“EventModelToken”,
useValue:EventSchema
},
{
提供:“DbConnectionToken”,
useFactory:async():Promise=>
等待mongoose.connect(在内存中),
},
],
}).compile();
eventService=module.get(EventsService);
});
按照文档中的规定,您可以使用值、工厂或类覆盖提供程序

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);
});

现在您可以在任何地方更改选项:)

我以前尝试过使用overrideProvider功能,但显然没有正确使用它。现在效果很好,谢谢你的帮助!
@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'})],
});