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

如何使用Sinon mock sort等链式方法,解决Repository单元测试报错问题

问题原因

你当前 stub 了 EventModel.find 方法后直接返回了普通值 stubValue,但 Mongoose 的 find 方法调用后会返回一个 Query 实例,该实例才挂载了 sort、lean、exec 等链式调用方法,缺少这些方法自然会抛出 sort is undefined 报错。

可行解决方案

方案1:手动构造支持链式调用的 stub 返回值(无需额外依赖)

直接让 find 方法返回的对象挂载所有需要的链式方法,配合 sinon.stub().returnsThis() 实现链式调用的支持,最后由 exec 方法返回你需要的模拟数据即可。
修改后的单元测试代码如下:

describe("getEvents", () => {
  it("should retrieve all events", async () => {
    // 先定义你要返回的模拟数据
    const mockEvents = [{
      _id: 'testId',
      createdAt: new Date('2024-01-01'),
      // 补充其他需要的 EventDocument 字段
    }]
    // stub find 方法,返回支持链式调用的对象
    const findStub = sinon.stub(EventModel, "find").returns({
      sort: sinon.stub().returnsThis(),
      lean: sinon.stub().returnsThis(),
      exec: sinon.stub().resolves(mockEvents)
    })

    const result = await eventRepository.findEventsByTriggerDate(testDate);

    expect(findStub.calledOnce).to.be.true;
    // 注意原方法返回的是数组,需要取对应位置的元素再断言
    expect(result[0].createdAt).to.equal(mockEvents[0].createdAt);

    // 测试完成后恢复 stub 避免影响其他用例
    findStub.restore()
  });
});

说明

  • returnsThis() 会让 stub 方法返回当前对象,完美适配链式调用场景,哪怕后续你调整了 sort、lean 的调用顺序也不需要修改 stub 逻辑
  • 不要忘记测试完成后调用 restore() 恢复原方法,避免污染其他测试用例

方案2:使用 sinon-mongoose 工具库(适合大量 Mongoose 测试场景)

如果你的项目有大量需要测试 Mongoose 查询的场景,可以引入 sinon-mongoose 扩展,它内置了对 Query 所有链式方法的 stub 支持,无需手动逐个定义。

额外注意

你原测试代码中直接断言 result.createdAt 是错误的,因为 Repository 层的 findEventsByTriggerDate 方法返回的是 EventDocument[] 数组,需要先取出数组中的对应元素再做字段断言。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 13:45:05