如何在NestJS的ProductController测试中Mock MongooseModule导入
在NestJS测试中Mock MongooseModule的方法
你的问题核心是ProductService依赖Mongoose注册的Product Model,直接运行现有测试会因为缺少Model依赖而失败。不需要Mock整个MongooseModule,只需为ProductService提供Mock的Model实例即可,具体步骤如下:
1. 导入必要工具
在测试文件顶部导入Nest提供的getModelToken工具函数,用来获取Model的注入令牌:
import { getModelToken } from '@nestjs/mongoose';
2. 创建Mock的Product Model
根据你的ProductService实际使用的Model方法,编写对应的Mock函数。比如常用的find、create方法:
// 模拟Product Model的核心方法 const mockProductModel = { find: jest.fn().mockResolvedValue([]), create: jest.fn().mockResolvedValue({ _id: 'mock-id', name: '测试商品' }), // 按需添加其他方法,比如findById、updateOne等 };
3. 修改测试模块配置
在Test.createTestingModule的providers数组中,注册Mock的Model,替换掉Mongoose提供的真实Model:
describe('ProductController', () => { let controller: ProductController; // 把mockProductModel定义在这里,方便所有测试用例访问 const mockProductModel = { find: jest.fn().mockResolvedValue([]), create: jest.fn().mockResolvedValue({ _id: 'mock-id', name: '测试商品' }), }; beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ controllers: [ProductController], providers: [ ProductService, // 注册Mock的Product Model,名称要和ProductModule中定义的一致 { provide: getModelToken('Product'), useValue: mockProductModel, }, ], }).compile(); controller = module.get<ProductController>(ProductController); }); it('should be defined', () => { expect(controller).toBeDefined(); }); // 示例:测试控制器的具体接口逻辑 it('should return all products', async () => { const testProducts = [{ _id: '1', name: '商品1' }, { _id: '2', name: '商品2' }]; // 修改Mock函数的返回值 mockProductModel.find.mockResolvedValue(testProducts); const result = await controller.getAllProducts(); // 假设控制器有该方法 expect(result).toEqual(testProducts); expect(mockProductModel.find).toHaveBeenCalledTimes(1); }); });
为什么这样做?
- 控制器测试的核心是验证控制器与Service的交互逻辑,无需依赖真实数据库连接
- 通过Mock Model,你可以完全控制数据返回,覆盖各种测试场景(空数据、异常、正常数据等)
内容的提问来源于stack exchange,提问作者DukeSmellington
相关产品推荐
相关产品推荐

