新闻详情

新闻详情

首页 / 资讯中心 / 详情

sinon 中 stub.resetHistory() 的完整指南:重置调用历史而不影响桩行为

发布时间:2026/9/25 11:36:19来源:尧图网络
sinon 中 stub.resetHistory() 的完整指南:重置调用历史而不影响桩行为
测试开发工具【免费下载链接】sinonTest spies, stubs and mocks for JavaScript.项目地址https://gitcode.com/gh_mirrors/si/sinon点击查看免费下载stub.resetHistory()是 Sinon.JS 为 stub桩函数提供的核心维护方法用于清空一个 stub 自创建以来的全部调用历史记录call history而不改变该 stub 已经配置好的行为behavior。在单元测试中它通常用于同一测试文件内的多阶段场景——例如先验证某次调用再重置计数继续验证下一轮调用避免反复重建 stub 或沙箱。读完本文你将掌握stub.resetHistory()的语义边界、底层实现原理、与stub.reset()/stub.resetBehavior()的区别以及如何通过sinon.resetHistory()批量重置整个沙箱内所有 fake、spy 和 stub 的历史。一、API 定位它属于 Stub API 的重置三兄弟之一在 Sinon.JS 的官方 Stub API 中见 docs/concepts/stubs/api/index.md 的 Methods 列表与重置相关的 API 共有三个它们覆盖了 stub 生命周期的不同维度API作用是否影响行为behavior是否影响历史historystub.resetHistory()仅重置调用历史❌ 不影响✅ 重置stub.resetBehavior()重置为默认行为返回undefined✅ 重置❌ 不影响stub.reset()同时重置行为与历史✅ 重置✅ 重置其中stub.reset()在官方文档中被明确描述为equivalent to calling bothstub.resetBehavior()andstub.resetHistory()等价于依次调用这两个方法见 docs/concepts/stubs/api/reset.md。因此理解resetHistory的关键就在于把它和行为严格区分开历史是它被怎么调用了行为是它被调用后返回什么/做什么。二、基本用法与官方测试用例官方为stub.resetHistory()提供的测试位于 docs/tests/docs/stubs/api/reset-history.test.js它直接演示了该 API 的完整语义import tap from tap; import * as sinon from sinon; tap.test(stub.resetHistory, (t) { const stub sinon.stub(); t.notOk(stub.called, stub.called is false initially); stub(); t.ok(stub.called, stub.called is true after call); stub.resetHistory(); t.notOk(stub.called, stub.called is false after resetHistory); t.end(); });这个用例揭示了三个要点初始状态新建的匿名 stubsinon.stub()called为false调用后执行一次stub()后called变为true重置后调用stub.resetHistory()后called又回到false仿佛从未被调用过。典型应用场景是在同一个it/test内做调用计数清零例如const spy sinon.spy(api, fetchData); // 第一轮验证 api.fetchData(/a); assert(spy.calledOnce); // 重置历史开始第二轮验证 spy.resetHistory(); api.fetchData(/b); api.fetchData(/c); assert(spy.calledTwice); // 计数从零重新开始不受第一轮影响注意resetHistory是 spy 与 stub 共有的能力stub 本身继承自 spy因此上述写法对两者均适用。三、底层实现resetHistory 到底清空了哪些字段要准确使用这个 API必须知道历史在实现层面究竟包含什么。resetHistory的实际实现位于 src/sinon/proxy.jsstub、spy、fake 共同继承自 proxy 的 APIresetHistory: function () { if (this.invoking) { const err new Error( Cannot reset Sinon function while invoking it. Move the call to .resetHistory outside of the callback., ); err.name InvalidResetException; throw err; } this.called false; this.notCalled true; this.calledOnce false; this.calledTwice false; this.calledThrice false; this.callCount 0; this.firstCall null; this.secondCall null; this.thirdCall null; this.lastCall null; this.lastArg null; this.args []; this.firstArg null; this.returnValues []; this.thisValues []; this.exceptions []; this.callIds []; this.errorsWithCallStack []; if (this.fakes) { forEach(this.fakes, function (fake) { fake.resetHistory(); }); } return this; },从源码结构可以梳理出三个值得注意的实现事实重置的字段清单它一次性清空的不只是called和callCount还包括所有与调用过程相关的记录——args每次调用的参数数组、thisValues每次调用的this上下文、returnValues返回值、exceptions抛出的异常、callIds调用顺序编号以及firstCall/secondCall/thirdCall/lastCall等便捷引用。也就是说calledWith、calledOn、returned、threw等基于历史数据的断言在重置后都会回到从未发生的状态。递归重置派生 fake如果该 stub 通过withArgs(...)创建了按参数匹配的派生 stub这些派生 fake 存放在this.fakes中resetHistory()会递归地对每个派生 fake 同样执行resetHistory()。这保证了主 stub 其withArgs分支的整体历史被一致性清空不会出现主桩已重置而分支计数残留的错乱。禁止在调用过程中重置如果resetHistory在 stub 自身的回调执行期间被调用this.invoking为真会抛出InvalidResetException错误提示把重置调用移到回调之外。这是为了防止在调用栈进行中清空记录导致内部状态不一致。此外resetHistory()返回thisstub 本身因此可以链式调用例如stub.resetHistory().returns(42)在重置历史后立即配置新行为。四、与 stub.reset() 的关系组合即reset()stub.reset()的实现位于 src/sinon/stub.jsreset: function () { this.resetHistory(); this.resetBehavior(); },可以看到reset()本质上就是resetHistory()与resetBehavior()的顺序组合。而resetBehavior()src/sinon/stub.js做的则是另一件事清空defaultBehavior、behaviors数组删除returnValue、returnArgAt、fakeFn等行为字段把returnThis/resolveThis置回false并同样递归处理withArgs派生 fake。它的效果是让 stub 回到未配置任何行为的默认状态——此时调用 stub 将返回undefined对应测试 docs/tests/docs/stubs/api/reset-behavior.test.js 中的断言。因此只想重新统计调用次数保留返回值/抛出异常等行为配置→ 用stub.resetHistory()只想撤掉行为配置但保留已发生的调用记录→ 用stub.resetBehavior()两者都要恢复出厂状态→ 直接用stub.reset()或依次调用两个方法。三者的官方对照说明分别见 docs/concepts/stubs/api/reset-history.md、docs/concepts/stubs/api/reset-behavior.md 与 docs/concepts/stubs/api/reset.md。五、沙箱级批量重置sinon.resetHistory() 与 sandbox.resetHistory()resetHistory不仅存在于单个 stub 上Sinon 还提供了沙箱sandbox级别的批量版本。官方文档 docs/concepts/sandboxes/api/reset-history.md 说明sandbox.resetHistory()会重置使用该沙箱创建的所有 fakes、spies 和 stubs的历史。由于 Sinon 根对象本身就是一个默认沙箱所以也可以直接调用sinon.resetHistory()。其实现位于 src/sinon/sandbox.jssandbox.reset function reset() { applyOnEach(collection, reset); applyOnEach(collection, resetHistory); }; sandbox.resetHistory function resetHistory() { for (let i 0; i collection.length; i) { const f collection[i]; const method f.resetHistory || f.reset; if (typeof method function) { method.call(f); } } };从源码可以看出两个细节sandbox.resetHistory()遍历沙箱的collection所有已创建的 fake/spy/stub对每个成员调用其resetHistory对于不支持resetHistory的成员则退化为调用reset。sandbox.reset()则会先对所有成员执行reset清空行为再执行resetHistory清空历史——这正好与单个 stub 上reset()的组合语义保持一致。沙箱级的历史重置测试见 docs/tests/docs/sandboxes/api/reset-history.test.js其验证路径与单个 stub 的测试完全对称创建 fake → 调用 → 断言called为真 →sinon.resetHistory()→ 断言called回到假。使用沙箱批量重置的典型写法const sandbox sinon.createSandbox(); const stubA sandbox.stub(api, methodA); const stubB sandbox.stub(api, methodB); api.methodA(); api.methodB(); assert(sandbox.assert.calledOnce(stubA)); // 一次调用清空沙箱内所有成员的历史 sandbox.resetHistory(); assert(!stubA.called !stubB.called);六、实践建议与注意事项区分历史与行为的使用时机当你在beforeEach或测试中途需要清零计数重新验证但又不想重新配置returns/throws等行为时resetHistory是唯一正确的选择如果误用reset()行为配置也会丢失stub 会退化回返回undefined。withArgs分支同步重置由于实现会递归重置fakes带参数匹配的派生 stub 历史也会一并清空无需手动逐个清理。不要在回调内部重置任何在 stub 执行过程中invoking状态调用resetHistory的写法都会抛出InvalidResetException请把重置移到调用完成之后。偏好沙箱级 API在sinon.createSandbox()场景下优先使用sandbox.resetHistory()或sandbox.reset()做统一清理再配合sandbox.restore()在测试结束后还原被替换的原方法避免手工维护零散的 stub 引用。文档对照完整的 Stub API 方法清单与各 API 的单独文档可在 docs/concepts/stubs/api/index.md 及其同目录下的reset.md、reset-behavior.md、reset-history.md中逐一查阅。小结stub.resetHistory()是 Sinon.JS 中精准重置能力的代表它只清空调用历史called、callCount、args、returnValues、thisValues、exceptions、callIds等全部记录保留已配置的行为并递归作用于withArgs派生 fake在实现层面它由 proxy 统一提供src/sinon/proxy.js在沙箱层面则由 src/sinon/sandbox.js 的resetHistory批量委托。配合stub.resetBehavior()行为维度与stub.reset()组合维度你可以精确控制测试中每一个 stub 的状态生命周期写出更清晰、更可控的单元测试。赞分享测试开发工具【免费下载链接】sinonTest spies, stubs and mocks for JavaScript.项目地址https://gitcode.com/gh_mirrors/si/sinon点击查看免费下载相关推荐Sinon sandbox.resetBehavior 完全指南批量重置 stub 行为而保留调用历史Sinon sandbox.resetBehavior 完全指南批量重置 stub 行为而保留调用历史 sandbox.resetBehavior 是 Sin测试开发工具Bokeh 数学符号渲染完全指南在图表与控件中使用 LaTeX 和 MathMLBokeh 数学符号渲染完全指南在图表与控件中使用 LaTeX 和 MathML Bokeh 原生支持在图表中渲染数学公式允许开发者使用 LaTeX 与 M测试开发工具sinon sandbox.reset() 详解重置 Stub 可变行为与 Fake/Spy/Stub 调用历史sinon sandbox.reset 详解重置 Stub 可变行为与 Fake/Spy/Stub 调用历史 导读 sandbox.reset 是 Sinon测试开发工具上一篇BullMQ 快速上手指南从安装、生产任务到 Worker 消费与事件监听下一篇PinWin窗口置顶工具3分钟掌握多窗口高效管理的终极秘诀创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

CSS3 Loading动画精选与实战:从选型到性能优化全指南 2026/9/26 0:41:49

CSS3 Loading动画精选与实战:从选型到性能优化全指南

前阵子帮一个项目做上线前的最后自查,其他问题都处理完了,唯独页面那个转圈loading在Windows的Firefox里纹丝不动。一开始以为是animation没加前缀,查完发现是全局样式把transform-origin改掉了,旋转中心整个偏移,动画…

阅读更多 →
UE5 Niagara粒子系统零基础入门:底层逻辑与实战避坑指南 2026/9/26 0:41:48

UE5 Niagara粒子系统零基础入门:底层逻辑与实战避坑指南

UE5的Niagara系统,这几年几乎是特效师和技术美术绕不开的话题。我在项目里被美术同事问过最多的一句话就是:"Niagara到底比老版Cascade强在哪?为什么新项目一定要用这个?"说实话,我刚接触Niagara的时候也懵了…

阅读更多 →
AI编程助手Claude Code、Codex、OpenCode一站式Docker环境配 TaoToken:config.toml 骨架与连通性验证 2026/9/26 0:41:42

AI编程助手Claude Code、Codex、OpenCode一站式Docker环境配 TaoToken:config.toml 骨架与连通性验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
山西恒山科技煤矿数字化建设来样定制生产厂家,成立多年广受信赖 2026/9/26 0:41:42

山西恒山科技煤矿数字化建设来样定制生产厂家,成立多年广受信赖

Q1:煤矿数字化建设为什么要选可定制的厂家? 很多煤矿在推进智能化升级的时候,都会遇到一个共性难题:不同矿井的资源条件、开采规模、现有系统基础都不一样,没有办法直接套用一套标准化的解决方案。如果强行用标准化产品&#xff…

阅读更多 →
口碑不错的开工奠基仪式策划团队能力调研报告 2026/9/26 0:41:42

口碑不错的开工奠基仪式策划团队能力调研报告

开工奠基仪式作为政企项目启动的核心仪式,直接关系到项目落地的品牌形象与社会关注度,其策划执行绝非简单的流程堆砌,而是需要结合场地特性、项目定位、合规要求,搭建兼具仪式感与传播性的活动闭环。不少从业者容易陷入误区&#…

阅读更多 →
Atlas 300V部署YOLO实战:昇腾推理卡从模型转换到性能调优全解析 2026/9/26 0:41:35

Atlas 300V部署YOLO实战:昇腾推理卡从模型转换到性能调优全解析

最近后台不少朋友都在问两个问题:Atlas部署YOLO到底怎么搞,以及Atlas 300V 24G这卡是不是运算加速卡。这俩问题一合起来,其实就是在问华为昇腾这套推理硬件到底能不能拿来跑自己手头的模型,值不值得入。这话题我最近正好折腾了一遍…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉