NestJS中mongoose-delete软删除单元测试报错:delete不是函数
解决NestJS中mongoose-delete软删除单元测试报错问题
问题原因
单元测试中创建的模型实例未加载mongoose-delete插件,导致实例上不存在delete方法,触发TypeError: this._geoRestrictionDocument.delete is not a function错误。
解决方案
方案1:在测试模块中手动加载插件
在测试模块的模型提供者中,手动为Schema应用mongoose-delete插件,确保测试用的模型实例包含该方法:
// geo-restriction.service.spec.ts import { Test, TestingModule } from '@nestjs/testing'; import { getModelToken } from '@nestjs/mongoose'; import * as mongoose from 'mongoose'; import * as mongooseDelete from 'mongoose-delete'; import { GeoRestrictionService } from './geo-restriction.service'; import { GeoRestriction, GeoRestrictionSchema } from './geo-restriction.schema'; describe('GeoRestrictionService', () => { let service: GeoRestrictionService; let model: mongoose.Model<GeoRestriction>; beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ providers: [ GeoRestrictionService, { provide: getModelToken(GeoRestriction.name), useFactory: () => { // 手动为Schema应用mongoose-delete插件 const schema = GeoRestrictionSchema; schema.plugin(mongooseDelete); return mongoose.model(GeoRestriction.name, schema); }, }, ], }).compile(); service = module.get<GeoRestrictionService>(GeoRestrictionService); model = module.get<mongoose.Model<GeoRestriction>>(getModelToken(GeoRestriction.name)); }); describe('delete', () => { it('should soft delete a geo restriction', async () => { // 创建带delete方法的实例 const mockDoc = new model({ /* 测试数据 */ }); jest.spyOn(model, 'findById').mockResolvedValue(mockDoc); jest.spyOn(mockDoc, 'delete').mockResolvedValue(mockDoc); await service.delete('test-id'); expect(model.findById).toHaveBeenCalledWith('test-id'); expect(mockDoc.delete).toHaveBeenCalled(); }); }); });
方案2:Mock delete方法(轻量测试)
如果仅需验证服务层逻辑,无需加载真实插件,可直接Mock模型实例的delete方法:
// 在测试用例中 it('should soft delete a geo restriction', async () => { const mockDoc = { delete: jest.fn().mockResolvedValue({}) } as unknown as GeoRestriction & mongoose.Document; jest.spyOn(model, 'findById').mockResolvedValue(mockDoc); await service.delete('test-id'); expect(model.findById).toHaveBeenCalledWith('test-id'); expect(mockDoc.delete).toHaveBeenCalled(); });
验证要点
- 确保服务层中调用的是文档实例的
delete方法(而非模型静态方法),与测试中的Mock逻辑匹配 - 若使用
mongoose-delete的静态方法(如model.deleteById),需对应Mock模型的静态方法
内容的提问来源于stack exchange,提问作者chandan barnwal
相关产品推荐
相关产品推荐

