在 Jest 中灵活切换手动 Mock 与实际模块实现

在 Jest 中灵活切换手动 Mock 与实际模块实现

本文深入探讨了在 jest 测试框架中,如何有效管理手动模拟(manual mock)与实际模块的切换使用。通过详细介绍 `jest.dontmock()` 和 `jest.resetmodules()` 这两个关键 api,文章提供了在特定测试场景下绕过全局手动模拟、调用真实模块实现的实用方法,并辅以代码示例和注意事项,旨在帮助开发者实现更灵活、精准的测试控制。

理解 Jest 模块模拟与缓存机制

在 Jest 中,当我们为某个模块(例如 axios)创建了手动模拟文件(如 __mocks__/axios.js),Jest 会在测试运行时自动使用这个模拟版本,而不是实际的 axios 包。这种机制在大多数情况下非常方便,它允许我们隔离外部依赖,专注于测试当前模块的逻辑。

然而,有时我们可能需要在同一个测试套件中,针对某些特定测试用例调用模块的真实实现。例如,在集成测试或端到端测试中,我们可能希望 axios 真正地发出 HTTP 请求。直接在测试内部使用 jest.mock(“axios”, () => jest.requireActual(“axios”)) 尝试覆盖模拟可能不会立即生效,这是因为 Jest 有一个模块注册表缓存机制。一旦模块被加载并模拟,其模拟版本就会被缓存起来,后续的 require 或 import 语句会直接从缓存中获取,而不会重新解析或应用新的模拟指令。

解决方案:jest.dontMock() 与 jest.resetModules()

为了在特定测试中绕过手动模拟并加载真实模块,我们需要结合使用 jest.dontMock(moduleName) 和 jest.resetModules()。

jest.dontMock(moduleName):这个 API 告诉 Jest 不要模拟指定的模块。它会阻止 Jest 使用 __mocks__ 目录下的手动模拟文件,而是加载模块的实际实现。

jest.resetModules():这个 API 用于重置 Jest 的模块注册表缓存。它会清除所有已加载模块的缓存,确保下一次 require 或 import 操作会重新加载模块,从而使得 jest.dontMock() 的效果得以应用。

重要提示: jest.resetModules() 必须在 jest.dontMock() 之前调用,或者至少在模块被 import 之前调用,以确保模块注册表被清除,并且 jest.dontMock() 能够影响到后续的模块加载行为。通常,我们会在 beforeEach 钩子中调用 jest.resetModules(),以确保每个测试用例都在一个“干净”的模块环境中运行。

实践示例

下面通过一个具体的例子来演示如何实现手动模拟与实际模块的切换。

假设我们有一个 axios 的手动模拟,它总是返回一个固定的假数据:

__mocks__/axios.js:

let mockAxios = jest.genMockFromModule('axios');// 为 get 方法提供一个默认的模拟实现mockAxios.get = jest.fn().mockResolvedValue({ data: 'fake' });export default mockAxios;

接着,我们有一个业务逻辑模块 main.ts,它使用了 axios 发送 HTTP 请求:

ViiTor实时翻译 ViiTor实时翻译

AI实时多语言翻译专家!强大的语音识别、AR翻译功能。

ViiTor实时翻译 116 查看详情 ViiTor实时翻译

main.ts:

import axios from 'axios';export function main() {  return axios.get('https://jsonplaceholder.typicode.com/todos/1');}

现在,我们编写测试文件 main.test.ts,其中包含一个使用模拟 axios 的测试和一个使用真实 axios 的测试:

main.test.ts:

describe('Axios 模块模拟与真实实现切换', () => {  // 在每个测试用例运行前重置模块注册表  // 这一步至关重要,它清除了之前测试可能留下的模块缓存,  // 确保每个测试用例都能根据其自身的模拟配置加载模块。  beforeEach(() => {    jest.resetModules();  });  test('应该使用模拟的 axios', async () => {    // 默认情况下,如果存在手动模拟,Jest 会使用它。    // 在此测试中,我们不需要额外的 dontMock,因为我们希望使用模拟。    const { main } = await import('./main'); // 导入 main 模块,此时 axios 会被模拟    const actual = await main();    console.log('使用模拟 axios 的结果:', actual?.data);    expect(actual?.data).toEqual('fake'); // 预期返回模拟数据  });  test('应该使用真实的 axios', async () => {    // 在这个测试用例中,我们明确告诉 Jest 不要模拟 axios    jest.dontMock('axios');    // 再次导入 main 模块。由于 resetModules 和 dontMock 的作用,    // 此时 main 内部的 axios 将是真实实现。    const { main } = await import('./main');     const actual = await main();    console.log('使用真实 axios 的结果:', actual?.data);    // 预期返回真实 API 的数据结构    expect(actual?.data).toHaveProperty('userId');    expect(actual?.data).toHaveProperty('id');    expect(actual?.data).toHaveProperty('title');    expect(actual?.data).toHaveProperty('completed');  });});

运行上述测试,你将观察到以下输出:

  console.log    使用模拟 axios 的结果: fake  console.log    使用真实 axios 的结果: { userId: 1, id: 1, title: 'delectus aut autem', completed: false }

这清楚地表明,第一个测试用例成功使用了手动模拟的 axios,而第二个测试用例通过 jest.dontMock(‘axios’) 和 jest.resetModules() 成功加载并使用了真实的 axios 模块,并从外部 API 获取了数据。

注意事项与最佳实践

jest.resetModules() 的位置: 最好将其放在 beforeEach 钩子中,以确保每个测试用例都从一个干净的模块状态开始。这可以避免测试之间的状态泄露,提高测试的独立性和可靠性。性能考量: jest.resetModules() 会清除模块缓存并重新加载所有模块,这可能会对测试运行时间产生轻微影响,尤其是在大型项目中。然而,对于大多数单元和集成测试场景,这种开销通常是可接受的,并且其带来的测试隔离性收益远大于性能损失。局部模拟: 如果你只是想在某个测试文件中对某个模块进行临时模拟,而不是全局手动模拟,可以使用 jest.doMock() 结合 jest.unmock()。但对于本文讨论的“绕过已存在的手动模拟”场景,jest.dontMock() 是更直接的方案。jest.requireActual() 的替代用途: jest.requireActual(moduleName) 通常用于在模拟文件中获取模块的真实实现,以便在模拟中部分地使用真实逻辑。例如:const actualAxios = jest.requireActual(‘axios’); mockAxios.post = actualAxios.post;。这与本文讨论的在测试中完全禁用模拟是不同的场景。

总结

通过熟练运用 jest.dontMock() 和 jest.resetModules(),开发者可以在 Jest 测试中获得对模块模拟行为的精细控制。这使得在同一个测试套件中,既能利用手动模拟进行隔离测试,又能按需调用真实模块进行更接近生产环境的集成测试,从而极大地提升了测试的灵活性和覆盖范围。理解并正确使用这些 Jest API 是编写健壮、可维护测试的关键。

以上就是在 Jest 中灵活切换手动 Mock 与实际模块实现的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/311441.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年11月5日 05:31:06
下一篇 2025年11月5日 05:32:15

相关推荐

  • 什么是加密世界的“乐高积木”?理解DeFi的可组合性

    DeFi可组合性指协议间如乐高积木般无缝集成,源于开源与无需许可特性,支持跨协议调用。1、所有接口公开,共享区块链状态,确保交易原子性;2、用户可通过Aave抵押ETH借稳定币,在Uniswap兑换更多ETH并循环抵押以构建杠杆,但需警惕清算风险;3、收益聚合器如Yearn自动将DAI分配至Comp…

    2025年12月9日
    000
  • 加密货币资产如何配置?新手入门级投资组合策略

    新手应以主流币为核心配置,60%-70%资金投向BTC和ETH,通过定投平摊成本,并选择合规平台保障安全;20%-25%布局潜力赛道,分散投资Layer2、AI与去中心化衍生品;10%-15%设为防御仓位,配置稳定币与质押资产以应对波动并获取收益。 对于刚进入币圈的新手,合理的资产配置是控制风险、实…

    2025年12月9日
    000
  • 如何查看瑞波币实时行情?哪些工具能提供准确数据?

    瑞波币实时行情显示,XRP价格在2.35至2.50美元区间波动,24小时成交量超18亿,市值约147亿美元,受ETF预期及链上大额转账影响,市场多空博弈加剧,投资者需关注2.40美元关键支撑位与监管动态。 查看瑞波币实时行情需借助专业数据平台,确保信息及时准确。 一、使用主流行情网站 专业的加密货币…

    2025年12月9日
    000
  • ENS 正式采用 Taiko 技术栈,助力 Namechain 在以太坊主网实现 ZK Rollup 扩容

    近日,ENS(以太坊域名服务)宣布正式采用 Taiko 技术栈,助力 Namechain 在以太坊主网实现 ZK Rollup 扩容。此举旨在提高 ENS 域名交易和管理的效率,同时降低交易成本,推动以太坊生态的可扩展性。 Taiko 技术栈与 ZK Rollup 优势 1、提高交易吞吐量:ZK R…

    2025年12月9日
    000
  • Merlin Chain(MERL)11月19日解锁3,614万枚代币,市值约1,249万美元

    Merlin Chain(MERL)将于 2025年11月19日 解锁 3,614万枚代币,按当前价格计算,总市值约为 1,249万美元。代币解锁通常会增加市场流动性,对价格可能产生短期波动,需要投资者关注。 MERL代币解锁影响 代币解锁可能带来的影响主要包括: 市场供应增加:新解锁的代币可能进入…

    2025年12月9日
    000
  • 2025潜力币:掘金未来十大虚拟货币

    在快速变化的数字资产领域,部分项目因其技术创新和生态系统建设而备受关注。本文将探讨十个在2025年值得关注的加密项目。 1、币安Binance 币安Binance官网入口: 币安BinanceAPP下载链接: 2、欧易okx 欧易okx官网入口: 欧易okxAPP下载链接: 一、Ethereum (…

    2025年12月9日
    000
  • 什么是EVM兼容?它为什么对公链生态如此重要?

    EVM兼容指区块链能运行以太坊虚拟机代码,使智能合约与以太坊生态工具无缝对接。其核心在于字节码、Gas模型、状态树和账户体系的完全对齐。具备该特性公链可复用Truffle、Hardhat、ethers.js等开发工具,降低迁移成本,缩短上线周期。开发者仅需复制合约代码、修改网络配置、连接存储即可部署…

    2025年12月9日
    000
  • 如何安全地使用交易所的API进行量化交易?API密钥泄露的风险有多大?

    必须防范API密钥泄露导致资产被盗,通过最小权限、IP白名单、环境变量存储、定期轮换及安全网络环境等多重措施保障量化交易安全。 正规靠谱的加密货币交易平台推荐: 欧易OKX: Binance币安: 火币Huobi: Gateio芝麻开门: 安全使用交易所API进行量化交易,需防范密钥泄露导致资产被盗…

    2025年12月9日
    000
  • 热门meme币前景:2026年可能突破1美元的三枚潜力股

    狗狗币技术面看涨,社区与名人效应驱动价格;Flockerz以DAO治理增强粘性;Pepe Unchained凭Layer2优势提升交易效率。 一、狗狗币(DOGE)的技术面与社区驱动分析 狗狗币作为meme币的开创者,其价格动力主要来源于强大的社区共识和外部名人效应。技术面上,长期形成的上升通道为其…

    2025年12月9日
    000
  • 如何为你的加密学习建立一个知识框架?从入门到精通的路径

    首先掌握区块链基础概念与术语,建立正确认知模型;接着学习共识机制、智能合约及Layer2技术,提升技术理解能力;再通过分析链上数据、市场指标与K线形态,培养市场分析技能;随后模拟项目研究,整合知识形成闭环;最后通过订阅优质资讯源与定期复盘,持续更新认知体系。 构建加密学习知识框架需系统化规划,从基础…

    2025年12月9日
    000
  • 哪些交易所支持瑞波币交易?如何比较手续费标准?

    瑞波币(XRP)可在Binance、OKX等主流中心化交易所及Uniswap等去中心化平台交易,支持法币兑换与多种交易对,适合不同用户需求。 目前多家主流交易所支持瑞波币交易,用户可通过多种渠道进行买卖。 一、主流中心化交易所 中心化交易所由专业平台运营,提供法币通道和丰富的交易对,适合大多数用户。…

    2025年12月9日
    000
  • 全面剖析:狗狗币的诞生历程、技术演进与市场潜力

    %ignore_a_1%以社区文化为核心,通过技术升级提升性能,采用通胀模型促进流通,获多国支付认可并拓展实际应用。 狗狗币(DOGE)作为最具代表性的模因币,其发展融合了社区文化、技术迭代与市场情绪。 Binance币安交易所 Binance币安注册入口: Binance币安APP下载: 欧易OK…

    2025年12月9日
    100
  • meme币AI整合:2025年后智能合约提升的价格上限探讨

    2025年后,Meme币与AI技术深度融合,通过动态流动性池优化、抗操纵预言机、社区情绪预测和去中心化治理加速四大机制提升价格稳定性与市场效率。 2025年后,Meme币与AI技术的深度整合正显著影响其价格潜力。智能合约自动化与数据驱动决策成为关键驱动力。 一、动态流动性池优化 通过AI模型实时分析…

    2025年12月9日
    000
  • 恒星币铭文最新状态查询方法有哪些?一文了解币圈

    可通过区块链浏览器、API接口或第三方平台查询恒星币铭文状态。一、使用Stellar Expert等浏览器输入地址或哈希,查看交易详情中的Memo字段及成功状态。二、调用Horizon API获取账户交易历史,解析JSON数据提取memo_type和memo内容。三、通过Satoshi Portal…

    2025年12月9日
    000
  • 如何设置“追踪止损”(Trailing Stop)?它和移动止损有什么不同,适合什么行情?

    追踪止损是一种动态风险管理工具,通过随价格有利变动调整止损位来锁定利润。它与移动止损为同一概念,英文均称Trailing Stop,核心功能是在趋势行情中让利润奔跑并控制回撤。该机制可在价格上涨时自动上移止损位,避免手动调整和情绪干扰。常见设置方式包括基于固定点数、百分比和技术指标三种类型。固定点数…

    2025年12月9日
    000
  • 火币HTX交易所登录专区入口 火币手机端APP下载渠道

    火币htx交易所(原“火币网”)是全球知名的数字资产交易平台之一,提供现货、合约、理财等多种交易服务。对于币圈新手而言,通过官方渠道访问火币官网入口并下载安装官方app,是保障账户安全和顺利入门的关键步骤。本文将详细介绍火币htx登录专区入口与官方app下载渠道,以及注册流程指南。 火币官网访问入口…

    2025年12月9日
    000
  • Chainlink (LINK)解决了什么问题?详解预言机赛道的龙头项目

    Chainlink通过去中心化预言机网络解决区块链与外部数据连接难题,一、打破信息孤岛,利用分布式节点从多源获取并验证链下数据,支持智能合约基于真实世界事件执行;二、提升数据安全,采用质押机制与声誉系统约束节点行为,防止单点故障与数据篡改;三、实现跨链互通,依托CCIP协议和独立验证网络,保障资产与…

    2025年12月9日
    000
  • SOL区块数据可以下载吗?运行全节点有什么作用与要求?

    运行Solana全节点可下载完整区块数据,需通过solana命令行工具初始化配置并连接主网,依赖高性能硬件与网络保障同步稳定。 sol区块数据可以下载,通过运行solana全节点即可获取完整的区块链数据。全节点能验证网络交易并增强去中心化安全性。 OKX安卓APP下载:(支持直接安装) OKX苹果A…

    2025年12月9日
    000
  • 币安Binance账号在线注册入口无需跳转 币安APP在线获取地址

    币安binance交易所是全球领先的数字资产交易平台,提供现货、合约及理财等多种功能。对于新手用户而言,通过官方渠道进行在线注册和下载官方app,是安全进入数字资产交易的第一步。本文将为您详细介绍币安binance账号在线注册入口及币安app在线获取地址。 币安官网在线注册入口 ① 打开浏览器,输入…

    2025年12月9日
    000
  • 欧易OKEX交易平台网页版官方入口 OKX交易平台app下载注册指南

    欧易okx交易平台(前称okex)是全球知名的数字资产交易所,支持现货交易、合约交易及理财等多元服务。对于新手用户来说,通过官方网页入口访问平台、下载安装官方app并完成注册,是安全进入币圈的关键第一步。本文将详细介绍okx官网官方入口、app客户端下载及账户注册流程。 OKX官网访问入口 ① 打开…

    2025年12月9日
    000

发表回复

登录后才能评论
关注微信