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

React/Jest:Mock npm包默认导出函数readXlsxFile遇问题

解决read-excel-file的readXlsxFile函数Mock问题

问题根源

  1. Mock方式错误:你用jest.spyOn(readXlsxFile, "default")的写法不对——readXlsxFile本身就是默认导出的函数,不是包含default属性的对象,导致Mock完全没生效。
  2. 假File对象缺失方法:你创建的假File没有arrayBuffer方法,但这是次要问题——只要Mock生效,原函数不会执行,这个错误就会消失。

修复方案

方案一:直接Mock整个模块

这种方式最简单,适合完全替代原函数的场景:

import { render, fireEvent, waitFor } from "@testing-library/react";
import readXlsxFile from "read-excel-file";
import Import from "./import";

const mockXlsxData = [
    ["Poste", "Designation", "Secteur", "Îlot", "Etat", "Arrêts planifiés/jour"],
    ["101003", "OOF_[OOF]", "[OOF]", "[OOF]", "OFF", 0],
];

// 提前Mock整个模块,返回预设的Promise结果
jest.mock("read-excel-file", () => jest.fn(() => Promise.resolve(mockXlsxData)));

test("check file (form submit)", async () => {
    const component = render(<Import />);
    
    // 传入简化的假文件(Mock生效后不需要真实文件内容)
    fireEvent.change(component.getByTestId("fileInput"), {
        target: {
            files: [new File([""], "test.xlsx", { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" })],
        },
    });
    
    // 提交表单触发异步逻辑
    fireEvent.submit(component.getByTestId("ImportForm"));
    
    // 等待异步操作完成后再做断言
    await waitFor(() => {
        // 这里添加你的业务断言,比如检查解析后的数据是否正确渲染
        // expect(component.getByText("101003")).toBeInTheDocument();
    });
    
    // 验证Mock函数被调用
    expect(readXlsxFile).toHaveBeenCalled();
});

方案二:正确Spy默认导出的函数

如果需要临时Mock并恢复原函数,用这种方式:

import { render, fireEvent, waitFor } from "@testing-library/react";
import * as readXlsxFileModule from "read-excel-file";
import Import from "./import";

const mockXlsxData = [
    ["Poste", "Designation", "Secteur", "Îlot", "Etat", "Arrêts planifiés/jour"],
    ["101003", "OOF_[OOF]", "[OOF]", "[OOF]", "OFF", 0],
];

test("check file (form submit)", async () => {
    const component = render(<Import />);
    
    // 正确Spy默认导出的函数,用mockResolvedValue简化Promise返回
    const mockReadXlsx = jest.spyOn(readXlsxFileModule, "default").mockResolvedValue(mockXlsxData);
    
    fireEvent.change(component.getByTestId("fileInput"), {
        target: {
            files: [new File([""], "test.xlsx", { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" })],
        },
    });
    
    fireEvent.submit(component.getByTestId("ImportForm"));
    
    await waitFor(() => {
        // 你的业务断言逻辑
    });
    
    expect(mockReadXlsx).toHaveBeenCalled();
    // 恢复原函数
    mockReadXlsx.mockRestore();
});

关键说明

你之前的报错是因为Mock没生效,实际执行了read-excel-file的原函数,而测试环境里的假File没有实现arrayBuffer方法。只要Mock正确生效,原函数不会被调用,这个错误就会自动消失。另外,异步测试必须配合async/await和waitFor,确保异步逻辑执行完成后再做断言。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 20:25:22