我想在我的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);
});
答案 0 :(得分:2)
如文档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'})],
});
现在,您可以随时随地更改选项:)