使用createTestingModule时如何获取动态模块的PrismaService实例?
问题描述
我有一个全局动态模块 PrismaModule,定义如下:
// prisma.module.ts import { DynamicModule, Global, Module } from '@nestjs/common' import { PrismaService } from 'nestjs-prisma' @Global() @Module({}) export class PrismaModule { static register(options: { databaseUrl: string }): DynamicModule { return { module: PrismaModule, providers: [ { provide: PrismaService, useFactory: () => new PrismaService({ prismaOptions: { datasources: { db: { url: options.databaseUrl, }, }, }, }), }, ], exports: [PrismaService], } } }
现在我用 Test.createTestingModule 测试非顶级模块 MyModule,该模块依赖这个全局动态模块。我按照技巧重写了模块引用:
// app.module.ts export const prismaModule = PrismaModule.register({ databaseUrl: process.env.DB_URL, }) @Module({ imports: [ // ... prismaModule, // ... ], }) export class AppModule { constructor() {} }
测试代码如下:
// my-module.test.ts import { prismaModule } from '../app.module' // ... const mockPrismaModule = PrismaModule.register({ databaseUrl: "<some connection string>", }) const moduleRef = await Test.createTestingModule({ imports: [prismaModule], controllers: [MyController], providers: [MyService], }) .overrideModule(prismaModule) .useModule(mockPrismaModule) .compile() const prismaService = mockPrismaModule.<...>
我想获取 mockPrismaModule 在 register() 过程中创建的 PrismaService 实例,试过用 mockPrismaModule.get(PrismaService),但它不像 Test.createTestingModule() 的返回结果那样能调用 get 方法,请问有没有办法实现?
解决方法
你不能直接从 mockPrismaModule(也就是 register 返回的动态模块对象)获取实例,因为它只是模块的元数据定义,不是已经实例化的模块引用。正确的做法是从编译后的 moduleRef 里获取:
const prismaService = moduleRef.get(PrismaService);
因为你已经用 overrideModule 把原模块替换成了 mockPrismaModule,编译后的测试模块里的 PrismaService 就是你通过 mockPrismaModule 配置创建的实例。
如果需要提前创建 mock 实例并注入(比如用 jest mock),可以换一种更直接的方式:直接在测试模块里覆盖 PrismaService 的提供者,而不是替换整个模块:
// 先创建mock实例 const mockPrismaService = new PrismaService({ prismaOptions: { datasources: { db: { url: "<some connection string>", }, }, }, }); const moduleRef = await Test.createTestingModule({ imports: [prismaModule], controllers: [MyController], providers: [MyService], }) .overrideProvider(PrismaService) .useValue(mockPrismaService) .compile(); // 这里获取的就是你提前创建的mock实例 const prismaService = moduleRef.get(PrismaService);
这种方式能让你完全控制 PrismaService 的实例,操作起来也更灵活。
内容的提问来源于stack exchange,提问作者mjarosie
相关产品推荐
相关产品推荐

