React/Jest:Mock npm包默认导出函数readXlsxFile遇问题
解决read-excel-file的readXlsxFile函数Mock问题
问题根源
- Mock方式错误:你用
jest.spyOn(readXlsxFile, "default")的写法不对——readXlsxFile本身就是默认导出的函数,不是包含default属性的对象,导致Mock完全没生效。 - 假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
相关产品推荐
相关产品推荐

