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

如何在Jest中正确Mock带回调的Mongoose Model.find方法?

等等,要去掉AI味,所以语言要更像stackoverflow的回答,比如用更直接的语气,不要太生硬。比如把问题场景改成“你已经能成功Mock Mongoose的Promise风格find方法,但在Mock回调风格的调用时遇到了TypeScript类型错误”,然后直接说原因和解决方案。

再调整一下:

如何在Jest中Mock Mongoose带回调的find方法(TypeScript)

你已经能成功Mock Promise风格的find调用:

// 业务代码
Model.find({ 'a': 'b' }).then(value => { /* ... */ }).catch(err => { /* ... */ });

// Mock代码
Model.find = jest.fn().mockResolvedValue({ 'hi': 'its me' });

但当使用回调风格的find时:

// 业务代码
Model.find({ 'a': 'b' }, (err: any, value: IModel[]) => {
  if (err) { /* 错误处理 */ }
  // 处理返回结果
});

你尝试的Mock代码触发了TypeScript错误:Type 'void' is not assignable to type 'Query<any, any, {}, IModel>'

Model.find = jest.fn((conditions, callback) => {
  callback(null, { 'oi': 'its a me' })
});

问题根源

  1. TypeScript将你的Mock匹配到了带projection/options参数的find重载版本,但你实际需要Mock的是仅接收filter和callback的重载。
  2. 核心问题:无论是否传入回调,Mongoose的find方法始终返回QueryWithHelpers实例,而你的Mock函数没有返回值(默认是void),不符合类型定义要求。

正确Mock实现

要让Mock同时满足执行回调和返回合法Query实例的要求,代码如下:

import { QueryWithHelpers } from 'mongoose';
import { IModel } from './your-model-file'; // 引入你的模型类型

Model.find = jest.fn((conditions, callback) => {
  // 执行传入的回调,注意find返回的是文档数组
  if (typeof callback === 'function') {
    callback(null, [{ oi: 'its a me' }]);
  }
  // 返回符合类型要求的空对象,用类型断言绕开TS检查
  return {} as QueryWithHelpers<IModel[], IModel, {}, IModel>;
});

如果需要模拟错误场景:

Model.find = jest.fn((conditions, callback) => {
  if (typeof callback === 'function') {
    callback(new Error('Mock database error'), null);
  }
  return {} as QueryWithHelpers<IModel[], IModel, {}, IModel>;
});

注意事项

  • 回调的第二个参数是文档数组(IModel[]),不是单个对象,业务代码里如果是单个文档应该用findOne,这里要对应find的返回值类型。
  • 如果你的业务代码还会对返回的Query做链式调用(比如.sort()),可以在返回的对象上添加对应的Mock方法:
    return {
      sort: jest.fn().mockReturnThis(),
      exec: jest.fn().mockResolvedValue([{ oi: 'its a me' }])
    } as QueryWithHelpers<IModel[], IModel, {}, IModel>;
    

内容的提问来源于stack exchange,提问作者</think_never_used_51bce0c785ca2f68081bfa7d91973934>

这样更自然,符合stackoverflow的回答风格,去掉了AI味,结构清晰,代码示例明确。现在整理成正确的Markdown格式,按照要求的规则来:

标题用#,二级标题用##,代码用```typescript,强调的话用*比如核心问题,不过这里用加粗的话是文本,因为Markdown里两个星号是加粗。

对,上面的内容里核心问题就是加粗,符合要求。然后末尾标注来源。

现在最终的回答就是这样。</think_never_used_51bce0c785ca2f68081bfa7d91973934># 如何在Jest中Mock Mongoose带回调的find方法(TypeScript)

你已经能成功Mock Promise风格的find调用:

// 业务代码
Model.find({ 'a': 'b' }).then(value => { /* ... */ }).catch(err => { /* ... */ });

// Mock代码
Model.find = jest.fn().mockResolvedValue({ 'hi': 'its me' });

但当使用回调风格的find时:

// 业务代码
Model.find({ 'a': 'b' }, (err: any, value: IModel[]) => {
  if (err) { /* 错误处理 */ }
  // 处理返回结果
});

你尝试的Mock代码触发了TypeScript错误:Type 'void' is not assignable to type 'Query<any, any, {}, IModel>'

Model.find = jest.fn((conditions, callback) => {
  callback(null, { 'oi': 'its a me' })
});

问题根源

  1. TypeScript将你的Mock匹配到了带projection/options参数的find重载版本,但你实际需要Mock的是仅接收filter和callback的重载。
  2. 核心问题:无论是否传入回调,Mongoose的find方法始终返回QueryWithHelpers实例,而你的Mock函数没有返回值(默认是void),不符合类型定义要求。

正确Mock实现

要让Mock同时满足执行回调和返回合法Query实例的要求,代码如下:

import { QueryWithHelpers } from 'mongoose';
import { IModel } from './your-model-file'; // 引入你的模型类型

Model.find = jest.fn((conditions, callback) => {
  // 执行传入的回调,注意find返回的是文档数组
  if (typeof callback === 'function') {
    callback(null, [{ oi: 'its a me' }]);
  }
  // 返回符合类型要求的空对象,用类型断言绕开TS检查
  return {} as QueryWithHelpers<IModel[], IModel, {}, IModel>;
});

如果需要模拟错误场景:

Model.find = jest.fn((conditions, callback) => {
  if (typeof callback === 'function') {
    callback(new Error('Mock database error'), null);
  }
  return {} as QueryWithHelpers<IModel[], IModel, {}, IModel>;
});

注意事项

  • 回调的第二个参数是文档数组(IModel[]),不是单个对象,业务代码里如果需要单个文档应该用findOne,要对应find的返回值类型。
  • 如果业务代码还会对返回的Query做链式调用(比如.sort()),可以在返回的对象上添加对应的Mock方法:
    return {
      sort: jest.fn().mockReturnThis(),
      exec: jest.fn().mockResolvedValue([{ oi: 'its a me' }])
    } as QueryWithHelpers<IModel[], IModel, {}, IModel>;
    

内容的提问来源于stack exchange,提问作者</think_never_used_51bce0c785ca2f68081bfa7d91973934>

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 03:15:50