如何在NestJS中模拟来自其他导入模块的注入连接?
解决方案:模拟导入模块中的MongoDB连接
针对你遇到的Nest can't resolve dependencies错误,核心问题是导入的ClubsModule无法获取到测试环境中的MongoDB连接实例。以下是两种可行的解决方法:
方案1:在测试模块中全局配置内存Mongo连接
直接在测试模块的imports中配置MongooseModule使用内存Mongo实例,让导入的ClubsModule自动共享该连接:
import { MongooseModule } from '@nestjs/mongoose'; import { MongoMemoryServer } from 'mongodb-memory-server'; import { Test } from '@nestjs/testing'; describe('YService.spec.ts in YModule', () => { let mongod: MongoMemoryServer; beforeAll(async () => { mongod = await MongoMemoryServer.create(); }); beforeEach(async () => { const module = await Test.createTestingModule({ providers: [ // YService及相关依赖 ], imports: [ // 配置Mongoose使用内存Mongo MongooseModule.forRootAsync({ useFactory: () => ({ uri: mongod.getUri(), }), }), ClubsModule, // 导入目标模块 ], }).compile(); }); afterAll(async () => { await mongod.stop(); }); });
这种方式无需手动覆盖提供者,ClubsService中的@InjectConnection()会自动注入测试环境的内存连接。
方案2:强制覆盖全局Connection提供者
如果ClubsModule内部自行初始化了Mongoose连接,可通过overrideProvider强制替换整个测试上下文的连接实例:
import { getConnectionToken } from '@nestjs/mongoose'; import { MongoMemoryServer } from 'mongodb-memory-server'; import { Connection, connect } from 'mongoose'; import { Test } from '@nestjs/testing'; describe('YService.spec.ts in YModule', () => { let mongod: MongoMemoryServer; let mongoConnection: Connection; beforeAll(async () => { mongod = await MongoMemoryServer.create(); const uri = mongod.getUri(); // 创建内存Mongo连接实例 const mongooseInstance = await connect(uri); mongoConnection = mongooseInstance.connection; }); beforeEach(async () => { const module = await Test.createTestingModule({ providers: [ // YService及相关依赖 ], imports: [ClubsModule], }) // 覆盖默认Connection令牌的提供者 .overrideProvider(getConnectionToken()) .useValue(mongoConnection) .compile(); }); afterAll(async () => { await mongoConnection.close(); await mongod.stop(); }); });
注意:如果
ClubsService使用的是命名连接(如@InjectConnection('customConn')),需在getConnectionToken()中传入对应名称:getConnectionToken('customConn')。
问题根源说明
你之前的代码无效,是因为导入的ClubsModule拥有独立的依赖上下文,默认不会共享测试模块中本地覆盖的提供者。上述两种方法要么让测试模块提供全局可用的连接,要么强制覆盖全局的Connection令牌,确保ClubsService能获取到模拟的连接实例。
内容的提问来源于stack exchange,提问作者mmm
相关产品推荐
相关产品推荐

