Nest单元测试:如何Mock跨模块导出的Repository依赖?
如何Mock其他模块导出的Repository(解决Nest单元测试依赖错误)
问题场景
尝试为StrategyRegistryModule编写单元测试时,因模块依赖AppOnboardingModule导出的AppOnboardingRepository,出现以下依赖解析错误:
Nest can't resolve dependencies of the recipientservice_AppOnboardingEntityRepository (?). Please make sure that the argument recipientserviceDataSource at index [0] is available in the TypeOrmModule context.
核心原因
测试代码直接导入了真实的AppOnboardingModule,该模块依赖TypeOrm的recipientservice数据源,但单元测试环境未配置该数据源,导致依赖链断裂。单元测试无需连接真实数据库,应Mock外部模块的导出依赖,而非导入完整模块。
解决方案
1. 移除真实模块的导入
在测试模块中删除AppOnboardingModule的导入,避免触发TypeOrm的数据源初始化逻辑。
2. 直接Mock目标Repository
针对AppOnboardingModule导出的AppOnboardingRepository,提供Mock实现:
- 若为自定义Repository(如代码中的
AppOnboardingRepository),直接以该类作为provider的标识; - 若为TypeOrm自动生成的Repository,使用
getRepositoryToken(Entity, 'connectionName')获取标识。
修改后的测试代码
// 定义Mock的Repository实现 const mockAppOnboardingRepository: any = { findOne: jest.fn(), fetchDeviceList: jest.fn(), fetchRecipientsFromRecGroupIds: jest.fn() }; beforeAll(async () => { const module = await Test.createTestingModule({ imports: [ StrategyRegistryModule, // 仅导入待测试的目标模块 WinstonModule.forRoot({ transports: [new winston.transports.Console()] }) ], providers: [ // Mock AppOnboardingModule导出的自定义Repository { provide: AppOnboardingRepository, useValue: mockAppOnboardingRepository }, // 若需同时MockTypeOrm自动生成的Entity Repository,添加以下配置 { provide: getRepositoryToken(AppOnboardingEntity, 'recipientservice'), useValue: mockAppOnboardingRepository }, CustomLoggerService ] }).compile(); // 获取测试用的服务实例 strategyRegistryService = module.get<StrategyRegistryService>(StrategyRegistryService); });
额外说明
- 使用
useValue而非useFactory更直接,除非需要动态创建Mock实例; - 若
StrategyRegistryModule自身导入了TypeOrmModule.forFeature([AppOnboardingEntity], 'recipientservice'),必须同时Mock该Entity对应的Repository,避免残留的TypeOrm数据源依赖。
内容的提问来源于stack exchange,提问作者malvi
相关产品推荐
相关产品推荐

