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

Vue3结合Jest+vue-test-utils测试时Mock API返回undefined如何解决

核心问题定位

  • 挂载组件错误:你要测试的是Parent组件的逻辑,但测试代码里mount的是Child组件,而且id是Parent的props,不是Child的。
  • wrapper 定义错误:你把wrapper写成了未执行的异步函数,实际拿到的是函数对象而非组件实例,无法调用查找/触发事件的方法。
  • Mock 时机错误:你先触发了open事件调用makeApiCall,之后才给makeApiCall加spy和mock返回值,前面的调用根本没有捕获到,也没有拿到模拟返回值,自然返回undefined。
  • 未等待异步逻辑完成:open是异步方法,触发事件后需要调用flushPromises等待所有异步逻辑执行完毕,再做断言。

修正后的测试代码

import { flushPromises, mount } from "@vue/test-utils";
import * as apiModule from "./api.js";
import Parent from "./Parent.vue"; // 引入要测试的父组件
import Child from "./Child.vue";

jest.mock("./api.js");

it("test api call", async () => {
  // 1. 先Mock API返回值,再挂载组件/触发逻辑
  const mockedResponse = {
    foo: "bar",
  };
  // 注意:如果你的makeApiCall内部已经处理了response.json()、直接返回业务数据,这里mock直接返回mockedResponse即可
  // 如果你要模拟的是原生fetch返回的Response对象,才保留带json()的结构
  const mockApiReturn = Promise.resolve(mockedResponse); 
  const spy = jest.spyOn(apiModule, "makeApiCall").mockReturnValueOnce(mockApiReturn);
  // 同时Mock mounted里调用的loadPricesFor,避免挂载时报错
  jest.spyOn(apiModule, "loadPricesFor").mockResolvedValueOnce([]);

  // 2. 正确挂载Parent组件,传入需要的props
  const wrapper = mount(Parent, {
    props: {
      id: "123",
    },
  });
  await flushPromises(); // 等待mounted里的异步逻辑执行完

  // 3. 触发子组件的open事件
  wrapper.findComponent(Child).vm.$emit("open");
  await flushPromises(); // 等待open方法里的异步API调用执行完

  // 4. 断言
  expect(spy).toHaveBeenCalledWith("123");
  // 这里可以继续断言Parent组件里修改后的数据字段
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.12 10:24:03