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

使用Jest Mock自定义component-lib库内部函数失效问题咨询

问题根因

  1. 导入顺序问题:如果测试文件中先导入了业务组件Main,再执行jest.mock,业务组件会提前拿到原始库的真实函数引用,后续mock不会覆盖已导入的依赖。虽然jest.mock默认会被提升到模块顶层,但如果配置了ESM模式或者导入路径有别名解析问题,很容易出现提升失效的情况。
  2. ES模块导出只读特性:ES模块的命名导出属性默认是只读的,直接修改从库中导入的函数属性会触发「仅存在getter方法」的报错。
  3. 重导出的引用问题:component-lib的index.js是二次导出内部模块的函数,如果mock时仅修改index.js层的导出,若库内部或者业务代码有其他路径的导入,会出现mock不生效的情况。

解决方案

方案1:调整mock位置+固定返回值

将jest.mock放在测试文件最顶部,所有业务代码导入之前执行,避免引用提前被捕获,混合CJS/ESM环境可显式声明__esModule属性:

// 测试文件最顶部先写mock,再导入其他内容
jest.mock('component-lib', () => {
  const actualLib = jest.requireActual('component-lib')
  return {
    ...actualLib,
    __esModule: true,
    isFeatureEnabled: jest.fn().mockReturnValue(false)
  }
})

// 后续再导入测试依赖和业务代码
import { render } from '@testing-library/react'
import Main from './Main'

describe('unit test', () => {
  it('Should send data', () => {
    render(<Main />)
    // 执行操作触发逻辑
  })
})

方案2:适配可变mock返回值需求,解决只读报错

如果需要在不同测试用例中修改mock返回值,通过jest.mocked(TS环境)或强制类型转换拿到可写的mock函数引用,避免直接修改ES模块只读属性:

// 顶部先导入库实例,再执行mock
import * as componentLib from 'component-lib'
jest.mock('component-lib', () => {
  const actualLib = jest.requireActual('component-lib')
  return {
    ...actualLib,
    __esModule: true,
    isFeatureEnabled: jest.fn()
  }
})

// 拿到可写的mock函数引用,无TS可写为 componentLib.isFeatureEnabled as jest.Mock
const mockIsFeatureEnabled = jest.mocked(componentLib.isFeatureEnabled)

import { render } from '@testing-library/react'
import Main from './Main'

describe('unit test', () => {
  // 每次用例执行前重置mock状态,避免用例间污染
  beforeEach(() => mockIsFeatureEnabled.mockReset())

  it('Should run disabled feature branch', () => {
    mockIsFeatureEnabled.mockReturnValue(false)
    render(<Main />)
    // 执行操作验证逻辑
  })

  it('Should run enabled feature branch', () => {
    mockIsFeatureEnabled.mockReturnValue(true)
    render(<Main />)
    // 执行操作验证逻辑
  })
})

方案3:直接mock函数原始路径(兜底方案)

如果上述方案均不生效,直接mock函数所在的原始内部模块路径,跳过外层重导出的引用问题:

// 直接mock函数的原始来源文件
jest.mock('component-lib/modules/features', () => {
  const actualModule = jest.requireActual('component-lib/modules/features')
  return {
    ...actualModule,
    __esModule: true,
    isFeatureEnabled: jest.fn().mockReturnValue(false)
  }
})

内容的提问来源于stack exchange,提问作者Lucas M.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 20:36:02