You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 19:42:41