Jest如何模拟ES6默认导出并修改其默认实现/返回值
解决React自定义Hook测试中mockImplementation报错问题
问题原因
你遇到的TypeError: _useCustomHook.default.mockImplementation is not a function报错,核心原因是你在jest.mock中直接返回了一个普通函数,而非Jest创建的mock函数。只有Jest生成的mock函数才具备mockImplementation、mockReturnValue这类方法。
修复步骤
1. 修改初始mock定义
将jest.mock中的default值改为jest.fn(),并设置初始返回值:
jest.mock("./useHook", () => ({ __esModule: true, // 用jest.fn()包裹初始返回值,让default成为一个mock函数 default: jest.fn(() => [false, jest.fn()]) }));
2. 修改测试用例中的mock返回值
现在useCustomHook已经是标准的Jest mock函数,可以直接用mockReturnValue修改返回值:
it("should render true when state is true", () => { useCustomHook.mockReturnValue([true, jest.fn()]); render(<App />); expect(screen.queryByText(/true/i)).toBeInTheDocument(); });
3. 可选:重置mock状态(避免测试用例污染)
在afterEach中除了清除mock调用记录,还可以重置mock的返回值到初始状态:
afterEach(() => { jest.clearAllMocks(); cleanup(); // 重置mock到初始返回值 useCustomHook.mockReturnValue([false, jest.fn()]); });
完整修复后的测试代码
import "@testing-library/jest-dom"; import { render, screen, cleanup } from "@testing-library/react"; import App from "./App"; import useCustomHook from './useHook'; // 修改后的mock定义 jest.mock("./useHook", () => ({ __esModule: true, default: jest.fn(() => [false, jest.fn()]) })); describe("testing App state", () => { afterEach(() => { jest.clearAllMocks(); cleanup(); // 重置mock到初始状态 useCustomHook.mockReturnValue([false, jest.fn()]); }); it("should render false when state is false", () => { render(<App />); expect(screen.queryByText(/false/i)).toBeInTheDocument(); }); it("should render true when state is true", () => { useCustomHook.mockReturnValue([true, jest.fn()]); render(<App />); expect(screen.queryByText(/true/i)).toBeInTheDocument(); }); });
其他可选方案:使用__mocks__目录
如果你倾向于用__mocks__目录管理mock,可以在项目根目录创建__mocks__/useHook.js:
// __mocks__/useHook.js export default jest.fn(() => [false, jest.fn()]);
然后测试代码中只需要保留jest.mock("./useHook"),后续同样可以用useCustomHook.mockReturnValue修改返回值,效果和上面一致。
内容的提问来源于stack exchange,提问作者0x5929
相关产品推荐
相关产品推荐

