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
相关产品推荐
相关产品推荐

