Jest无法正确Mock函数:SvelteKit应用测试报错排查
Jest Mock SvelteKit +page.server load 函数报错:"received value must be a mock or spy function"
你遇到的问题有两个核心原因:
- 提前导入
load导致拿到的是原始函数而非Mock函数 - 直接渲染
+page.svelte时,SvelteKit不会自动触发服务端load函数,组件仅接收data作为props
解决方案一:修正Mock引用并手动传递组件数据
修改测试代码,移除提前导入的load,通过jest.requireMock获取Mock后的函数,同时在渲染组件时手动传入Mock数据:
import { describe, jest } from "@jest/globals"; import { render, screen } from "@testing-library/svelte"; import Page from "./+page.svelte"; // 先执行Mock,Jest会自动将该语句提升到所有导入前 jest.mock("./+page.server", () => ({ __esModule: true, load: jest.fn(() => ({ agents: [ { uuid: "", displayName: "a", description: "", displayIcon: "", fullPortrait: "", background: "", role: { displayName: "", displayIcon: "" }, abilities: [] }, { uuid: "", displayName: "b", description: "", displayIcon: "", fullPortrait: "", background: "", role: { displayName: "", displayIcon: "" }, abilities: [] }, { uuid: "", displayName: "c", description: "", displayIcon: "", fullPortrait: "", background: "", role: { displayName: "", displayIcon: "" }, abilities: [] }, ] })) })); // 从Mock后的模块中获取load函数 const { load } = jest.requireMock("./+page.server"); describe("testing the home page", () => { it("should render all agents on the page", async () => { // 获取Mock的返回数据 const mockData = await load(); // 渲染组件时传入data props render(Page, { props: { data: mockData } }); // 验证Mock函数被调用 expect(load).toHaveBeenCalled(); // 验证组件渲染内容 expect(screen.getAllByTestId("agent-a")).toHaveLength(1); expect(screen.getAllByTestId("agent-b")).toHaveLength(1); expect(screen.getAllByTestId("agent-c")).toHaveLength(1); }) })
解决方案二:单独测试load函数逻辑
如果你需要测试load函数本身的业务逻辑(比如是否正确调用valorant.getAgents),可以单独对+page.server.js进行测试:
import { describe, jest } from "@jest/globals"; import { load } from "./+page.server"; import valorant from "../lib/services/valorant"; // Mock valorant服务模块 jest.mock("../lib/services/valorant", () => ({ getAgents: jest.fn(() => Promise.resolve([ { uuid: "", displayName: "a", description: "", displayIcon: "", fullPortrait: "", background: "", role: { displayName: "", displayIcon: "" }, abilities: [] }, { uuid: "", displayName: "b", description: "", displayIcon: "", fullPortrait: "", background: "", role: { displayName: "", displayIcon: "" }, abilities: [] }, { uuid: "", displayName: "c", description: "", displayIcon: "", fullPortrait: "", background: "", role: { displayName: "", displayIcon: "" }, abilities: [] }, ])) })); describe("load function", () => { it("should fetch agents and return them correctly", async () => { const result = await load(); expect(valorant.getAgents).toHaveBeenCalled(); expect(result.agents).toHaveLength(3); expect(result.agents[0].displayName).toBe("a"); }) })
错误原因说明
- Mock引用问题:ES模块的
import会被提升到模块顶部,你提前导入的load是原始模块的导出,而Jest的jest.mock虽然也会被提升,但无法覆盖已经导入的原始函数引用。必须通过jest.requireMock在Mock完成后获取Mock后的模块导出。 - 组件测试逻辑问题:
+page.server.js中的load函数是SvelteKit在服务器端路由处理阶段执行的,直接渲染+page.svelte组件时,组件不会自动调用该函数,仅会接收data作为props渲染内容,因此需要手动传入测试数据。
内容的提问来源于stack exchange,提问作者Evandro Viegas
相关产品推荐
相关产品推荐

