如何使用Jest对JavaScript函数进行Stub/Mock?——针对getM异步函数的测试实现问询
如何正确Mock/Stub异步函数getM中的依赖来完成测试
首先得指出你之前尝试的几个问题,咱们再一步步修正:
- 你混淆了
m对象本身和它的实例:getM里是先调用m.getInstance()拿到实例,再调用实例上的getAll(),而你直接去mockm.getAll(),这根本不是函数里实际调用的那个方法。 - 你构造的测试数据结构不对:函数里要取每个元素的
index属性,但你给的数组元素是{ 0: { rate: 2 }, 1:{ rate: 1 }, length: 2 },这种结构map后只会得到undefined数组,不符合预期。 - 异步测试没处理好:你没使用
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
相关产品推荐
相关产品推荐

