Jest单元测试中如何对controller层的数据库返回结果进行mock?
Controller层数据库返回结果Mock实现方案
你当前使用的是Mongoose + Jest + Supertest的技术栈,无需连接真实数据库,直接Mock数据库操作方法即可完成单元测试,具体实现如下:
实现步骤
- 首先确认你测试文件中导入了
Image模型,我们会对该模型的数据库操作方法做模拟 - 替换原有测试代码为以下版本:
import request from 'supertest'; import app from '../path/to/your/app'; // 替换为你的app实例实际路径 import Image from '../path/to/your/ImageModel'; // 替换为你的Image模型实际路径 // 自动Mock整个Image模型,所有方法调用不会触发真实数据库操作 jest.mock('../path/to/your/ImageModel'); describe("It should be get method", () => { // 可选:统一重置Mock调用记录,避免多测试用例互相干扰 beforeEach(() => { jest.clearAllMocks(); }); test("get all image url", async () => { // 1. 预设要返回的假数据 const mockImages = [ { _id: '1', url: 'https://example.com/1.jpg', date: new Date('2024-01-02') }, { _id: '2', url: 'https://example.com/2.jpg', date: new Date('2024-01-01') } ]; // 2. Mock链式调用:Image.find({}).sort() // find方法返回带sort方法的对象,sort方法异步返回预设的假数据 const mockSort = jest.fn().mockResolvedValue(mockImages); (Image.find as jest.Mock).mockReturnValue({ sort: mockSort }); // 3. 发起请求 const res = await request(app).get("/api/v1/all"); // 4. 断言验证 expect(res.statusCode).toBe(200); expect(res.body).toEqual(mockImages); // 验证返回数据和我们预设的一致 expect(Image.find).toHaveBeenCalledWith({}); // 验证find方法参数正确 expect(mockSort).toHaveBeenCalledWith({ date: -1 }); // 验证sort方法参数正确 }); });
代码说明
- 因为
Image.find({})返回的是Mongoose的Query实例,支持链式调用.sort(),所以Mock时需要让find返回一个带sort方法的模拟对象,保证调用链不会报错 mockResolvedValue用来给异步方法设置返回值,对应原Controller代码里的await调用- 所有验证点覆盖了状态码、返回值、数据库方法调用参数三个维度,保证逻辑正确性
扩展方案
如果后续有更多链式调用(比如limit、skip),按照同样的逻辑在find返回的模拟对象中添加对应的Mock方法即可。
内容的提问来源于stack exchange,提问作者Al Imran Hossain
相关产品推荐
相关产品推荐

