NestJS结合MongoDB单元测试报循环依赖错误如何解决
问题根因
这个循环依赖报错和Service、Controller之间的双向引用无关,核心原因是Mongoose模型的注入令牌和GroceryService这个Provider的默认注入令牌重名,导致Nest解析依赖时出现逻辑死循环,触发循环依赖检测。
你代码里的两处错误配置直接导致了这个问题:
GroceryService构造函数中,@InjectModel()传入的令牌字符串错写为'GroceryService',和当前Service类的默认注入令牌完全一致GroceryListModule中MongooseModule.forFeature配置的模型name字段也错写为'GroceryService',和Service令牌冲突
修复方案
1. 修正Service中的模型注入
打开grocery-list.service.ts,修改构造函数里的@InjectModel参数,将模型令牌改为和Mongoose注册的实体名一致(也就是你的Schema对应的实体名Grocery):
@Injectable() export class GroceryService { constructor( // 把原来的'GroceryService'改成Grocery.name,或者硬编码字符串'Grocery' @InjectModel(Grocery.name) private readonly groceryModel: Model<GroceryDocument>, ) {} // 其余业务代码保持不变 }
2. 修正Module中的Mongoose模型注册
打开grocery-list.module.ts,修改MongooseModule.forFeature的配置,保证模型name和注入时的令牌完全一致:
@Module({ imports: [ // 把原来name字段的'GroceryService'改成Grocery.name MongooseModule.forFeature([{ name: Grocery.name, schema: GroceryModel }]), ], controllers: [GroceryListController], providers: [GroceryService], }) export class GroceryListModule {}
提示:推荐统一使用
Schema类.name的方式获取模型名,避免硬编码字符串写错导致的令牌不匹配问题。
单元测试配置注意事项
修复主代码后,编写单元测试配置TestingModule时也需要注意令牌匹配问题,不要手动写错Provider的注入令牌:
- 导入Service的同时,需要用Nest Mongoose提供的
getModelToken()方法获取正确的模型注入令牌来提供Mock实现,不要随便硬编码令牌字符串 - 正确的单测Provider配置示例:
import { getModelToken } from '@nestjs/mongoose'; import { Grocery } from './schemas/grocery-list.schema'; // TestingModule配置中的providers部分 providers: [ GroceryService, { provide: getModelToken(Grocery.name), useValue: { // 按业务用到的方法写Mock实现即可 find: jest.fn(), findById: jest.fn(), findByIdAndUpdate: jest.fn(), findByIdAndRemove: jest.fn(), save: jest.fn(), create: jest.fn(), exec: jest.fn(), }, }, ],
按以上步骤修改后,循环依赖报错就会消失,不需要额外加forwardRef()。
内容的提问来源于stack exchange,提问作者Johhny Effren
相关产品推荐
相关产品推荐

