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

Jest中ES6模块重导出后的Mock问题求助

Fixing Jest Mocking Issues with ES6 Re-Exports (export * from)

Hey there, I've run into this exact issue before—when you use export * from to re-export submodule functions, Jest can struggle to intercept those exports because the re-export doesn't create a local binding in the parent module. Let's break down why this happens and how to fix it with your project structure.

First, let's recap your code setup to make sure we're on the same page:

Your Project Files

root/index.js

import { sayHello } from "./greeter";
export const greet = (name) => sayHello(name);

greeter/index.js

export * from "./submodule.js";

greeter/submodule.js

export const sayHello = (name) => `Hello, ${name}!`;

The problem arises because when you try to mock ./greeter directly, Jest can't properly override the sayHello function since it's just a forwarded export from submodule.js. Here are two reliable solutions:


Solution 1: Mock the Submodule Directly

The simplest fix is to mock the actual submodule that contains sayHello, instead of the parent greeter module. Since greeter/index.js only re-exports from submodule.js, any import from greeter will resolve to the mocked submodule's exports.

Update your test file (__tests__/index.js) like this:

import { greet } from '../index';

// Mock the submodule where sayHello is defined
jest.mock('../greeter/submodule', () => ({
  sayHello: jest.fn((name) => `Mocked Hello, ${name}!`)
}));

describe('greet function', () => {
  it('should invoke the mocked sayHello function', () => {
    const result = greet('Alice');
    
    // Verify the mock worked
    expect(result).toBe('Mocked Hello, Alice!');
    expect(require('../greeter/submodule').sayHello).toHaveBeenCalledWith('Alice');
  });
});

This works because all references to sayHello (including those imported through ./greeter) will use the mocked version from submodule.js.


Solution 2: Mock the Greeter Module with Explicit Re-Export

If you need to mock the greeter module directly (for example, if it has other exports you want to control), you can create a mock factory that re-exports the mocked submodule:

import { greet } from '../index';
import { sayHello } from '../greeter/submodule';

// First mock the submodule
jest.mock('../greeter/submodule', () => ({
  sayHello: jest.fn((name) => `Mocked Hello, ${name}!`)
}));

// Then mock the greeter module to re-export the mocked submodule
jest.mock('../greeter', () => ({
  ...jest.requireActual('../greeter'), // Keep any real exports if needed
  sayHello: sayHello
}));

describe('greet function', () => {
  it('should use the mocked sayHello from the greeter module', () => {
    const result = greet('Bob');
    
    expect(result).toBe('Mocked Hello, Bob!');
    expect(sayHello).toHaveBeenCalledWith('Bob');
  });
});

This approach ensures that the greeter module's sayHello export points to your mocked function, even though it's originally a re-export.


Quick Check: Babel Configuration

Make sure your Babel setup is compatible with Jest. If you're using @babel/preset-env, ensure it's configured to handle ES modules correctly (Jest typically expects CommonJS, so setting modules: 'commonjs' in your Babel config for test environments can help avoid unexpected behavior).

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 08:15:46