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

如何使用Jest对JavaScript函数进行Stub/Mock?——针对getM异步函数的测试实现问询

如何正确Mock/Stub异步函数getM中的依赖来完成测试

首先得指出你之前尝试的几个问题,咱们再一步步修正:

  1. 你混淆了m对象本身和它的实例:getM里是先调用m.getInstance()拿到实例,再调用实例上的getAll(),而你直接去mockm.getAll(),这根本不是函数里实际调用的那个方法。
  2. 你构造的测试数据结构不对:函数里要取每个元素的index属性,但你给的数组元素是{ 0: { rate: 2 }, 1:{ rate: 1 }, length: 2 },这种结构map后只会得到undefined数组,不符合预期。
  3. 异步测试没处理好:你没使用async/await等待异步结果,测试会直接跳过断言就结束了。

下面以Jest(前端最常用的测试框架)为例,给出完整的正确测试实现:

第一步:Mock目标依赖

假设m是从某个模块导出的(比如import m from './m-module'),我们先mock整个模块:

jest.mock('./m-module'); // 替换成你实际的m模块路径

第二步:编写测试用例

我们需要覆盖两种场景:ms有值且有长度的正常情况,以及ms为空或无长度的边界情况。

import getM from './path-to-getM'; // 替换成getM所在的文件路径
import m from './m-module';

describe("getM test", () => { 
  // 测试正常场景:ms存在且有元素,返回index数组
  it("should return array of index values when ms is valid", async () => {
    // 1. 定义符合要求的测试数据:每个元素都有index属性
    const mockMsData = [
      { index: 10 },
      { index: 20 },
      { index: 30 }
    ];

    // 2. Mock实例的getAll方法,让它返回resolved的测试数据
    const mockInstance = {
      getAll: jest.fn().mockResolvedValue(mockMsData)
    };
    // 让m.getInstance()返回这个mock实例
    m.getInstance.mockReturnValue(mockInstance);

    // 3. 异步调用getM并等待结果
    const result = await getM();

    // 4. 断言结果符合预期
    expect(result).toEqual([10, 20, 30]);
    // 额外断言方法调用次数,确保逻辑走对了
    expect(m.getInstance).toHaveBeenCalledTimes(1);
    expect(mockInstance.getAll).toHaveBeenCalledTimes(1);
  });

  // 测试边界场景:ms为空或无长度,返回空数组
  it("should return empty array when ms is null or empty", async () => {
    const mockInstance = {
      getAll: jest.fn()
    };
    m.getInstance.mockReturnValue(mockInstance);

    // 测试ms为null的情况
    mockInstance.getAll.mockResolvedValue(null);
    let result = await getM();
    expect(result).toEqual([]);

    // 测试ms为空数组的情况
    mockInstance.getAll.mockResolvedValue([]);
    result = await getM();
    expect(result).toEqual([]);
  });
});

额外小建议

你的getM函数里有个容易混淆的点:const m = m.getInstance();这里变量名m覆盖了外层的m对象,虽然语法合法,但可读性很差,建议改成:

async function getM() { 
  const instance = m.getInstance(); // 把变量名改成instance,避免混淆
  const ms = await instance.getAll(); 
  let array = []; 
  if (ms && ms.length) { 
    array = ms.map((item) => item.index); // 这里的参数名也别用m了,改成item更清晰
  } 
  return array; 
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 22:03:16