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

Jest无法正确Mock函数:SvelteKit应用测试报错排查

Jest Mock SvelteKit +page.server load 函数报错:"received value must be a mock or spy function"

你遇到的问题有两个核心原因:

  1. 提前导入load导致拿到的是原始函数而非Mock函数
  2. 直接渲染+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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 00:06:24