首页/新闻资讯/正文详情

Sinon sandbox.replace() 完全指南:安全替换对象属性并自动还原

发布时间:2026/9/25 8:53:14 来源:云帆数科 栏目:资讯中心
Sinon sandbox.replace() 完全指南:安全替换对象属性并自动还原
测试开发工具【免费下载链接】sinonTest spies, stubs and mocks for JavaScript.项目地址https://gitcode.com/gh_mirrors/si/sinon点击查看免费下载Sinon 的sandbox.replace()用于在测试中临时替换对象上的任意属性方法、字符串、数值乃至 fake/spy/stub并将原始值登记在沙箱的还原队列中随sandbox.restore()一并自动恢复。它省去了手动保存与还原原值的样板代码是隔离被测对象依赖、注入测试替身的核心手段。读完本文你将掌握replace()的参数规则、同类型校验、异常边界、访问器属性的替代方案replaceGetter/replaceSetter及其底层还原机制。方法签名与基本语义sandbox.replace是沙箱 API 中的一个方法官方文档定义如下sandbox.replace(object, property, replacement);其语义为将object上的property属性替换为replacement参数并返回replacement。它属于 沙箱 API 方法列表 中的一员从sinon5.0.0起sinon根对象本身就是一个默认沙箱因此可以直接调用sinon.replace(...)无需手动创建沙箱。替换过程并非简单的属性赋值——沙箱会在背后记录一个还原器restorer当调用sandbox.restore()时会把属性还原为替换前的值从而保证测试之间互不污染。在 src/sinon/sandbox.js 中可以找到该方法的真实实现其执行流程包含四道校验见下文异常与边界一节随后通过push(fakeRestorers, getFakeRestorer(object, property))登记还原器再执行object[property] replacement完成替换。返回值返回 replacement 本身replace()会返回传入的replacement参数便于链式使用或立即持有引用。这一点在 test/src/sandbox-test.js 中有对应测试将replacement传入后断言返回值actual与replacement严格相等。一个实用的写法是让替换函数直接作为返回值被捕获const sandbox sinon.createSandbox(); const object { method() { return original; } }; const fakeMethod sandbox.replace(object, method, sinon.fake.returns(mocked)); fakeMethod(); // mocked object.method(); // mockedreplacement 可以是任意值这是replace()与replaceGetter/replaceSetter的一个关键差异replacement可以是任何类型的值不限于函数。官方文档明确说明它可以包含fakes、spies和stubs。具体来说函数替换函数最常见的场景例如用 stub 替换被测模块依赖的方法字符串/数值等原始值替换同类型值如替换配置对象的字段fake/spy/stub 替换方法替换后该属性立即拥有 Sinon 的断言与行为能力。test/src/sandbox-test.js 中的测试证明了非函数属性字符串同样可以被替换并在restore()后还原。同类型校验不允许跨类型替换虽然replacement可以是任意值但原属性与替换值必须是同一 JavaScript 类型。源码中的verifySameType校验src/sinon/sandbox.js会对比typeof original与typeof replacementif (originalType ! replacementType) { throw new TypeError(Cannot replace ${originalType} with ${replacementType}); }对应测试位于 test/src/sandbox-test.js用函数替换字符串属性 → 抛出Cannot replace string with function用字符串替换函数属性 → 抛出Cannot replace function with string。这一设计避免了替换后调用方行为不可预期的隐性故障例如把方法误替换成字符串导致运行期TypeError: not a function。异常与边界情况官方文档明确指出Attempting to replace an already replaced value causes an exception.尝试替换一个已被替换的值会抛出异常。结合源码replace()在赋值前会依次执行四道校验校验步骤触发条件异常信息源码位置checkForValidArguments属性不存在无属性描述符Cannot replace non-existent property X. Perhaps you meant sandbox.define()?src/sinon/sandbox.jscheckForValidArgumentsreplacement为undefinedExpected replacement argument to be defined同上verifyNotReplaced该属性已被同一沙箱替换过Attempted to replace X which is already replacedsrc/sinon/sandbox.jsthrowOnAccessors属性是 getterUse sandbox.replaceGetter for replacing getterssrc/sinon/sandbox.jsthrowOnAccessors属性是 setterUse sandbox.replaceSetter for replacing setters同上verifySameType原值与替换值类型不一致Cannot replace X with Ysrc/sinon/sandbox.js几个值得注意的细节重复替换限制无论是函数还是字符串同一对象同一属性在同一沙箱内只能替换一次第二次调用会抛TypeError。测试见 test/src/sandbox-test.js。非可写属性的陷阱如果属性由Object.defineProperty定义为writable: false但仍 configurablereplace()通过赋值方式写入时会抛原生错误Cannot assign to read only property ...且属性保持不变相关测试见 test/src/sandbox-test.js。访问器属性请使用 replaceGetter / replaceSetter官方文档强调replace()只作用于非访问器non-accessor属性。对于 getter/setter应当改用sandbox.replaceGetter(object, property, replacement)替换 getterreplacement必须是函数sandbox.replaceSetter(object, property, replacement)替换 setterreplacement必须是函数。若对访问器属性调用replace()会直接抛出Error而非TypeError提示改用对应方法见 test/src/sandbox-test.js。这两个方法同样支持替换继承来的访问器并在restore()后还原测试见 test/src/sandbox-test.js。如果你的确需要用赋值方式替换访问器属性例如对象同时定义了 getter 与 setter、且底层状态由外部变量承载replace()还有一个非文档化的变体sandbox.replace.usingAccessor(object, property, replacement)它跳过访问器检测、直接走赋值路径测试示例见 test/src/sandbox-test.js。日常测试优先使用replaceGetter/replaceSetter即可。与 restore() 的生命周期管理自动还原replace()的最大价值在于与sandbox.restore()配合实现自动清理。还原流程在 src/sinon/sandbox.js 中实现restore()会逆序执行fakeRestorers数组中的还原器再逆序对collection中的 fake 逐个调用restore。每个还原器由getFakeRestorer生成src/sinon/sandbox.js其还原策略是描述符敏感的属性原本是对象自有属性记录替换前的完整属性描述符还原时通过Object.defineProperty恢复——包括enumerable、writable等属性特征而不仅仅是值属性是继承自原型链的替换会在对象上创建自有属性shadowing还原时执行delete object[property]移除该自有属性使原型上的原值重新可见。test/src/sandbox-test.js 对这两种还原路径分别做了验证还原后自有属性恢复原描述符如enumerable: false保持原样继承属性则被取消遮蔽、恢复读取原型值。看一个官方文档测试中的完整生命周期示例来自 docs/tests/docs/sandboxes/api/restore.test.jsconst obj { one: 1, two: 2, three: 3 }; sinon.replace(obj, one, apple); sinon.replace(obj, two, banana); sinon.replace(obj, three, cherry); // obj 现在为 { one: apple, two: banana, three: cherry } sinon.restore(); // obj 恢复为 { one: 1, two: 2, three: 3 }与 sandbox.define() 的区别替换 vs 定义replace()要求属性必须已经存在否则抛出Cannot replace non-existent property ... Perhaps you meant sandbox.define()?。这个错误信息同时指向了沙箱的另一方法sandbox.define(object, property, value)实现见 src/sinon/sandbox.jsreplace替换已存在的属性要求同类型define在对象上新增一个原本不存在或来自原型但非自有的属性同样会被沙箱登记并在restore()时删除且不要求类型一致。两条路径的错误信息互为提示define对已存在属性也会提示Perhaps you meant sandbox.replace()?测试见 test/src/sandbox-test.js。选择原则很简单属性原本就有就用replace原本没有就用define。完整实战示例以下示例改编自官方文档测试 docs/tests/docs/sandboxes/api/replace.test.js演示了默认沙箱下的最小用法import * as sinon from sinon; // sinon 根对象即默认沙箱 const myObject { myMethod: function () { return apple pie; }, }; sinon.replace(myObject, myMethod, function () { return strawberry; }); const result myObject.myMethod(); // result strawberry方法已被替换 sinon.restore(); // myObject.myMethod 恢复为返回 apple pie 的原函数结合 stub 的行为能力做依赖替换const sandbox sinon.createSandbox({ useFakeTimers: true }); const service { fetchData: () Promise.resolve(real data) }; // 用 stub 替换方法并预置返回值 const stub sandbox.replace( service, fetchData, sandbox.stub().resolves(mocked data), ); await service.fetchData(); // mocked data stub.calledOnce; // true sandbox.restore(); // 同时清理 stub 与替换常见注意事项小结replace()每次调用前都会校验未被替换过同一属性的重复替换会抛异常需要先restore()或使用不同沙箱替换值必须与原始属性同类型否则抛TypeError访问器属性getter/setter请改用replaceGetter/replaceSetterrestore()是描述符敏感的自有属性按原描述符还原继承属性通过删除自有遮蔽属性还原若目标属性尚未定义应使用sandbox.define()而不是replace()默认沙箱sinon根对象已具备全部沙箱 API除非需要独立配置如单独的useFakeTimers、injectInto等否则无需手动createSandbox。赞分享测试开发工具【免费下载链接】sinonTest spies, stubs and mocks for JavaScript.项目地址https://gitcode.com/gh_mirrors/si/sinon点击查看免费下载相关推荐Sinon Sandbox 的 replaceSetter精确替换对象 Setter 的完整指南Sinon Sandbox 的 replaceSetter精确替换对象 Setter 的完整指南 导读 sandbox.replaceSetter objec测试开发工具CVAT 半自动与自动标注Serverless AI 工具安装与部署指南CVAT 半自动与自动标注Serverless AI 工具安装与部署指南 导读 本文面向希望在自托管 CVATComputer Vision Annota测试开发工具HivisionIDPhotosAI 证件照生成器CPU 30 秒出成品照HivisionIDPhotosAI 证件照生成器CPU 30 秒出成品照 入职前 1 小时发现交上去的蓝底证件照不合规格打印店又已打烊。Hivisio测试开发工具上一篇UpscalerJS 开源项目入门指南下一篇Sveltia CMS移动端体验响应式设计如何完美适配不同设备创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关推荐

华为FTTR全光家庭网:光纤入室解决WiFi6卡顿与多终端抢带宽
华为FTTR全光家庭网:光纤入室解决WiFi6卡顿与多终端抢带宽

简介:本资源为华为FTTR全光家庭网络创新解决方案的完整技术白皮书PDF,面向通信工程师、宽带网络规划人员、智慧家庭方案集成商及运营商装维技术人员,聚焦解决大户型Wi-Fi覆盖弱、千兆宽带实际速率不足、多终端卡顿掉线等家庭网络核心痛点。文… · 2026/9/25 8:53:14

河北欧米奇西点西餐学校行业口碑如何
河北欧米奇西点西餐学校行业口碑如何

核心定位河北欧米奇西点西餐学校是中国东方教育集团旗下经石家庄市批准设立的正规西式餐饮职业学校,作为河北省西式餐饮专业人才培养重点基地,核心面向15-18岁青少年提供技能学历双提升的西式餐饮技能培训服务,深耕行业三十余年,已… · 2026/9/25 8:53:14

RisingWave 流式并行度统一配置设计解析:streaming_parallelism 参数语义、解析规则与旧参数迁移指南
RisingWave 流式并行度统一配置设计解析:streaming_parallelism 参数语义、解析规则与旧参数迁移指南

数据库流处理后端数据工程 【免费下载链接】risingwave Event streaming platform for agentic AI. Continuously ingest, transform, and serve event streams in real time, at scale. 项目地址: https://gitcode.com/gh_mirrors/ri/risingwave 点击查看 免费下载… · 2026/9/25 8:53:07

Blender模型格式转换 — 4个节点打通FBX/GLB/USD互通
Blender模型格式转换 — 4个节点打通FBX/GLB/USD互通

Blender模型格式转换 — 4个节点打通FBX/GLB/USD互通 【免费下载链接】awesome-blender 🪐 A curated list of awesome Blender addons, tools, tutorials; and 3D resources for everyone. 项目地址: https://gitcode.com/GitHub_Trending/aw/awesome-blender … · 2026/9/25 9:37:52

2026年液压油缸推力大的品牌是哪个,国德液压源头实力厂商推荐
2026年液压油缸推力大的品牌是哪个,国德液压源头实力厂商推荐

2026年液压油缸推力大的品牌推荐——常州国德液压源头实力厂商,常州国德液压机械有限公司专注液压油缸、液压系统及成套设备研发制造,可提供定制化液压解决方案,以高可靠、长寿命的产品为工业装备输出稳定动力。品牌基础概况常州国德液压机械… · 2026/9/25 9:37:46

从snap.php到在线拍照:PHP文件上传与图像处理全链路实战
从snap.php到在线拍照:PHP文件上传与图像处理全链路实战

看到 http://www.cameroid.com/snap.php 这个地址,我第一反应是:老站长应该都记得这种"在线拍照"页面的标准长相——Flash 拉起摄像头,选个滤镜或相框,咔嚓一下,后端一个 PHP 文件接收照片,生成缩… · 2026/9/25 9:37:27

PHP对接EOS区块链:从RPC到签名推送的完整指南
PHP对接EOS区块链:从RPC到签名推送的完整指南

我第一次在搜索框里敲下php <<<eos的时候&#xff0c;搜索结果有点滑稽——左边是 PHP heredoc 语法讲解&#xff0c;右边是 EOS 区块链相关的帖子。这个组合并非巧合&#xff1a;<<<EOS在 PHP 里是合法的 heredoc 定界符&#xff0c;EOS 同时又是一条公链的… · 2026/9/25 9:37:27

Claude Code 快速上手,看这一篇就够了:TaoToken 统一 Key 接入与 settings.json 配置实战
Claude Code 快速上手,看这一篇就够了:TaoToken 统一 Key 接入与 settings.json 配置实战

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

ISG信息安全竞赛题型全解析:五大考点与备考路径
ISG信息安全竞赛题型全解析:五大考点与备考路径

简介&#xff1a;ISG信息安全竞赛题目类型文档&#xff0c;面向CTF初学者及备战ISG赛事的参赛者&#xff0c;系统梳理了比赛组织方式与题目体系。文档参照CTF竞赛模式&#xff0c;详解Web漏洞与渗透、软件逆向、漏洞挖掘利用、密码学原理及应用、杂项等五大类考点的具体能力要求… · 2026/9/25 9:37:21

数值优化(Numerical Optimization)学习系列-03-共轭梯度方法(Conjugate Gradient)
数值优化(Numerical Optimization)学习系列-03-共轭梯度方法(Conjugate Gradient)

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

创维E900V22D刷机全攻略:S905L3SB芯片兼容性解析与救砖实战
创维E900V22D刷机全攻略:S905L3SB芯片兼容性解析与救砖实战

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

MQTT协议原理与Broker服务器搭建实战:从Mosquitto到EMQX
MQTT协议原理与Broker服务器搭建实战:从Mosquitto到EMQX

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

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码