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

求助:Jest中Mock ES6模块命名导出失败的问题

在Jest中Mock ES6模块命名导出失败的问题

我之前成功实现过在Jest里Mock ES6模块的命名导出,但现在找不到旧代码了。参考Stack Overflow相关问题后还是没能成功Mock。

我的ES6模块CatService代码如下:

export default "default"

export const getCatFact = () => ({fact: "cats are quadrupeds"}); 

这个模块被下面的React组件使用:

import React from "react";
import { getCatFact } from "./CatService";

const Component = () => {
  const {fact} = getCatFact(); 
  return <div data-testid="my-div">{fact}</div>
}

export default Component;

我试过参考Andy的已采纳答案来Mock:

import React from "react";
import { render, screen } from "@testing-library/react";
import '@testing-library/jest-dom'
import Component from "./Component";


test("mock an es6 module", async () => {
    const mockCatFact = jest.fn();

    mockCatFact.mockImplementation(() => ({fact: "mocked"}));
    
    
    jest.mock('./CatService', () => ({
        __esModule: true, 
        default: "mockedDefaultExport",
        getCatFact: mockCatFact
      }));
    
    
    render(
        <Component />
    );
    
    const myDiv = await screen.findByTestId("my-div")
    expect(myDiv).toHaveTextContent("mocked");//失败!值未被Mock
});

也试过类似falsarella的方法:

import React from "react";
import { render, screen } from "@testing-library/react";
import '@testing-library/jest-dom'
import Component from "./Component";
import { getCatFact } from "./CatService";


test("mock an es6 module", async () => {
   getCatFact.mockImplementation(() => ({fact: "mocked"}));
    // 报错:"TypeError: _CatService.getCatFact.mockImplementation is not a function"
    
    render(
        <Component />
    );
    
    const myDiv = await screen.findByTestId("my-div")
    expect(myDiv).toHaveTextContent("mocked");//失败!值未被Mock
});

两种方法都没生效,还是拿到未Mock的值。请问我哪里错了?


问题原因及解决方案

第一种方法失效原因

jest.mock是被Jest自动提升到模块顶部执行的,你在测试函数里定义的mockCatFact在jest.mock执行时还未初始化,导致Mock的是一个无效变量,自然无法生效。

修正后的第一种方法

把jest.mock移到模块顶层,直接在Mock工厂函数中定义mock逻辑,或者后续动态修改返回值:

import React from "react";
import { render, screen } from "@testing-library/react";
import '@testing-library/jest-dom'
import Component from "./Component";
import { getCatFact } from "./CatService";

// 移到模块顶层,Jest会自动提升执行
jest.mock('./CatService', () => ({
  __esModule: true, 
  default: "mockedDefaultExport",
  getCatFact: jest.fn()
}));

test("mock an es6 module", async () => {
  // 动态设置mock返回值
  getCatFact.mockReturnValue({fact: "mocked"});
  
  render(<Component />);
  
  const myDiv = await screen.findByTestId("my-div")
  expect(myDiv).toHaveTextContent("mocked");
});

第二种方法失效原因

直接调用getCatFact.mockImplementation报错,是因为原方法并非jest mock函数。可以用jest.spyOn来替换目标方法,无需Mock整个模块:

import React from "react";
import { render, screen } from "@testing-library/react";
import '@testing-library/jest-dom'
import Component from "./Component";
import * as CatService from "./CatService";

test("mock an es6 module with spyOn", async () => {
  // 用spyOn创建mock函数并替换原方法
  const mockGetCatFact = jest.spyOn(CatService, 'getCatFact')
    .mockImplementation(() => ({fact: "mocked"}));
  
  render(<Component />);
  
  const myDiv = await screen.findByTestId("my-div")
  expect(myDiv).toHaveTextContent("mocked");
  
  // 测试结束后恢复原方法,避免影响其他测试
  mockGetCatFact.mockRestore();
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 12:57:10