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

使用Jest模拟mongoose connection.db.collection时结果数组为空的问题

问题分析与修复方案

核心问题

  • jest.mock 放置位置错误:jest.mock('mongoose') 必须放在模块作用域(import 语句之后、测试函数之外),放在测试函数内部不会生效,导致模拟逻辑无法覆盖真实的mongoose对象。
  • 模拟对象结构不符:MongoDB的find()方法返回的是Cursor对象,而非直接的结果数组。你需要模拟这个Cursor对象,并让它的toArray()方法返回预期的数组Promise,而不是直接让find()返回数组Promise。

修正后的测试代码

import mongoose from 'mongoose';

// 必须放在模块作用域,确保mock在测试执行前生效
jest.mock('mongoose');

describe('mocking test suite', () => {
  it('should return expected array from mocked find', async () => {
    // 模拟MongoDB Cursor对象,实现toArray方法
    const mockCursor = {
      toArray: jest.fn().mockResolvedValue([
        {
          _id: mongoose.Types.ObjectId('77f6803bdd3e32292f4e4977'),
          data: 'something',
        },
        {
          _id: mongoose.Types.ObjectId('88f6803bdd3e32292f4e4988'),
          data: 'another thing',
        },
      ])
    };

    // 逐层模拟mongoose的嵌套结构
    mongoose.connection.db.collection.mockReturnValue({
      find: jest.fn().mockReturnValue(mockCursor)
    });

    const result = await mongoose.connection.db.collection('test').find();
    const arr = await result.toArray();

    expect(result).toBeDefined();
    expect(arr).toHaveLength(2);
    // 额外验证调用链,确保模拟逻辑正确触发
    expect(mongoose.connection.db.collection).toHaveBeenCalledWith('test');
    expect(result.toArray).toHaveBeenCalled();
  });
});

补充说明

  • 逐层模拟嵌套对象:mongoose的connection.db.collection是多层嵌套结构,必须确保每一层的mock都正确返回预期对象,避免出现undefined调用方法的情况。
  • 贴合真实API行为:严格按照MongoDB的实际调用逻辑模拟,find()返回Cursor实例,toArray()才是获取最终结果的方法,这样模拟逻辑和真实代码的调用链完全匹配。

内容的提问来源于stack exchange,提问作者kpollock

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 05:25:22