在 NestJS Jest 测试中覆盖提供程序
Posted
技术标签:
【中文标题】在 NestJS Jest 测试中覆盖提供程序【英文标题】:Overriding providers in NestJS Jest tests 【发布时间】:2019-02-05 07:03:59 【问题描述】:我想在我的 NestJS 应用程序中使用内存中的 Mongo 实例来模拟数据以进行测试。我有一个数据库提供程序,它使用 mongoose 连接到我的生产数据库,它是我的数据库模块的一部分,然后又被导入到其他模块中。
我试图在我的 Jest 测试中覆盖数据库提供程序,以便可以使用内存中的 Mongo 实例。
这是数据库模块:
import Module from '@nestjs/common';
import databaseProviders from './database.providers';
@Module(
providers: [...databaseProviders],
exports: [...databaseProviders],
)
export class DatabaseModule
和databaseProvider:
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);
);
【问题讨论】:
【参考方案1】:如文档 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')],
);
现在您可以在任何地方使用它来更改选项 :)
【讨论】:
我之前尝试过使用 overrideProvider 功能,但我显然没有正确使用它。现在完美运行,感谢您的帮助!以上是关于在 NestJS Jest 测试中覆盖提供程序的主要内容,如果未能解决你的问题,请参考以下文章
如何在测试 React.js App 时从 Jest 获得测试覆盖率?
如何用 Jest 单元测试覆盖 TypeORM @Column 装饰器?