
测试开发工具【免费下载链接】sinonTest spies, stubs and mocks for JavaScript.项目地址https://gitcode.com/gh_mirrors/si/sinon点击查看免费下载导读sinon.match.symbol是 Sinon 匹配器Matcher体系中用于强制校验参数必须是Symbol类型的专用匹配器。在编写测试时当被测函数接收 Symbol 作为参数例如键、枚举标识或迭代器协议符号而你又想确保断言不会被字符串、对象等近似值蒙混过关时sinon.match.symbol就是最直接的表达方式。本文将以官方文档 symbol.md 为主体结合仓库中的测试用例与源码实现讲透它的匹配语义、验证方式、使用场景与底层调用链让你能安全地将它用于 spy、stub 与 assert 的各种断言场景。匹配器Matcher机制速览在深入sinon.match.symbol之前先明确它所属的体系。Sinon 官方文档 Matchers 总览 明确指出Matchers can be passed as arguments tospy.calledOn,spy.calledWith,spy.returnedand the correspondingsinon.assertfunctions as well asspy.withArgs. Matchers allow to be either more fuzzy or more specific about the expected value.即匹配器是一类期望值描述符可被当作参数传给以下断言入口spy.calledOn文档匹配调用时的this值spy.calledWith文档匹配调用参数spy.returned文档匹配返回值对应的sinon.assert系列函数文档如assert.calledWithMatchspy.withArgs文档按参数筛选 spy 的调用记录。匹配器允许你表达模糊匹配例如任意字符串、任意数字或精确类型匹配例如必须是 Symbol。sinon.match.symbol属于后者它把匹配标准收窄到 ECMAScript 原生的Symbol类型上。sinon.match.symbol的官方语义sinon.match.symbol的官方定义极其简洁就一句话symbol.mdRequires the value to be aSymbol.翻译过来就是要求被匹配的值必须是一个Symbol。这意味着传入Symbol(test)这类用户创建的 Symbol →通过传入Symbol.iterator、Symbol.toStringTag这类内建的 well-known Symbol →通过传入字符串Symbol(test)即使内容长得像 Symbol→不通过传入任何对象例如{ type: symbol }→不通过。它的判定依据是值的运行时类型而不是值的外形或字符串描述这一点与sinon.match.string、sinon.match.number等同类类型匹配器保持一致的语义。测试用例官方行为验证仓库中与该文档对应的官方测试位于 symbol.test.js它使用 tap 测试框架完整覆盖了上述四种情形是对sinon.match.symbol行为最权威的验证import tap from tap; import * as sinon from sinon; tap.test(sinon.match.symbol, (t) { const fake sinon.fake(); fake(Symbol(test)); t.doesNotThrow(() { sinon.assert.calledWithMatch(fake, sinon.match.symbol); }, should accept Symbol); fake(Symbol.iterator); t.doesNotThrow(() { sinon.assert.calledWithMatch(fake, sinon.match.symbol); }, should accept well-known Symbol); fake.resetHistory(); fake(Symbol(test)); t.throws( () sinon.assert.calledWithMatch(fake, sinon.match.symbol), /expected fake to be called with match/, should reject string ); fake.resetHistory(); fake({ type: symbol }); t.throws( () sinon.assert.calledWithMatch(fake, sinon.match.symbol), /expected fake to be called with match/, should reject object ); t.end(); });逐段解读这个测试接受普通 Symbolfake(Symbol(test))之后assert.calledWithMatch(fake, sinon.match.symbol)不会抛出异常说明用户创建的带描述 Symbol 可以正常通过匹配接受 well-known Symbolfake(Symbol.iterator)同样通过断言。这确认了匹配器对内置协议符号如Symbol.iterator、Symbol.asyncIterator、Symbol.hasInstance等同样生效并不局限于用户自定义 Symbol拒绝字符串fake(Symbol(test))后调用同样的断言会抛出异常异常消息匹配/expected fake to be called with match/。这表明长得像 Symbol 的字符串不会被误判为 Symbol拒绝对象fake({ type: symbol })同样触发断言失败说明携带type: symbol属性的普通对象也无法通过匹配。测试中两次fake.resetHistory()用于清空调用历史保证每个断言只针对当前这一次调用这也是使用 Sinon spy/fake 时的良好实践。底层原理匹配器如何被消费sinon.match.symbol之所以能无缝用于calledWith、calledOn、assert.calledWithMatch、mock 期望校验等多种入口是因为 Sinon 在多个消费点上统一通过match.isMatcher(...)识别传入的是一个匹配器然后调用其test(value)方法完成判定。从源码可以梳理出三条关键调用链1. spy 调用记录的 this 匹配proxy-call.jsconst callProto { calledOn: function calledOn(thisValue) { if (match.isMatcher(thisValue)) { return thisValue.test(this.thisValue); } return this.thisValue thisValue; }, // ... };当calledOn收到的参数是一个匹配器时走thisValue.test(this.thisValue)路径——即用匹配器去测试真实调用时的this值。这也解释了为什么匹配器包括sinon.match.symbol能用于calledOn场景。2. mock 期望的参数校验mock-expectation.jsfunction verifyMatcher(possibleMatcher, arg) { const isMatcher match.isMatcher(possibleMatcher); return (isMatcher possibleMatcher.test(arg)) || true; }verifyMatcher同样遵循是匹配器就调用test的约定使sinon.match.symbol可以直接写进 mock 的expects(...).withExactArgs(...)等期望里。3. 断言失败信息的格式化spy-formatters.jsif (match.isMatcher(expectedArg)) { message colorSinonMatchText(expectedArg, calledArg); }断言失败时Sinon 会对匹配器进行特殊着色与格式化输出让expected fake to be called with match ...这类错误信息更易读。在 assert.js 中calledWithMatch断言对应的失败模板为expected %n to be called with match %D与测试中断言t.throws(..., /expected fake to be called with match/)观察到的消息格式完全吻合。Symbol 在 Sinon 内部的另一处使用非枚举类型标记值得一提的是Symbol 不仅是sinon.match.symbol匹配的目标类型Sinon 自身在实现上也依赖 Symbol 的唯一性 非枚举特性。在 sinon-type.js 中const sinonTypeSymbolProperty Symbol(SinonType); // ... set(object, type) { Object.defineProperty(object, sinonTypeSymbolProperty, { value: type, configurable: false, enumerable: false, }); }, get(object) { return object object[sinonTypeSymbolProperty]; },Sinon 用Symbol(SinonType)作为内部属性键通过Object.defineProperty将其设置为不可枚举enumerable: false从而在对象上标注类型信息spy、stub、fake 等同时避免该标记出现在for...in、Object.keys()或 JSON 序列化中。这从侧面说明了 Symbol 作为隐形标识符的工程价值——当你需要为系统内对象附加元数据、又要保证外部接口不被污染时Symbol 键是标准做法。而sinon.match.symbol恰好就是为验证这类使用模式而存在的类型匹配器。实战应用场景结合上述行为与源码证据sinon.match.symbol的典型应用场景包括1. 校验以 Symbol 作为键或标识的函数调用const token Symbol(request-id); const handler sinon.fake(); const client { send: (id) handler(id) }; client.send(token); // 校验确实收到的是 Symbol 标识而不是字符串 sinon.assert.calledWithMatch(handler, sinon.match.symbol);当 API 约定使用 Symbol 作为内部标识避免与字符串命名空间冲突时用sinon.match.symbol能在不关心具体是哪个 Symbol 的情况下只校验类型正确。2. 与spy.withArgs组合做调用分拣const spy sinon.spy(); spy(Symbol.iterator); spy(plain string); const symbolCalls spy.withArgs(sinon.match.symbol); symbolCalls.calledOnce; // true只有第一次调用被筛出参考 withArgs 文档withArgs允许按匹配器筛选调用记录与sinon.match.symbol组合即可快速统计传入了 Symbol 参数的调用次数。3. 校验迭代器协议相关实现const obj { [Symbol.iterator]: function* () { yield 1; } }; const stub sinon.stub(obj, Symbol.iterator); // ... 触发迭代 stub.calledWithMatch(sinon.match.symbol); // 校验入参是 Symbol 类型如前所述well-known Symbol如Symbol.iterator同样能被sinon.match.symbol接受因此可用于校验实现了迭代器协议的对象——注意sinon.stub也支持以 Symbol 作为属性名进行打桩。注意事项与边界它是类型匹配不是值匹配sinon.match.symbol只检查typeof value symbol不关心具体是哪个 Symbol。若要匹配某个特定的 Symbol 值应直接传入该 Symbol 本身例如fake.calledWith(specificSymbol)匹配器无法表达等于某个具体 Symbol。字符串描述不影响判定Symbol(x)和Symbol(y)是不同值但都会被sinon.match.symbol接受而x、new String(x)则一律拒绝。这与测试用例中拒绝字符串Symbol(test)的行为一致。兼容性前提Symbol是 ES2015ES6特性使用本匹配器需要运行环境支持原生 Symbol。在较老的 Node.js 或浏览器环境中typeof Symbol可能不是function此时应像 assert-test.js 中测试symbol method names时做的那样先判断typeof Symbol ! function并跳过相关用例。适用于所有支持匹配器的断言入口calledWith、calledOn、returned、assert.calledWithMatch、withArgs以及 mock 期望均可使用消费逻辑统一由match.isMatchertest(value)协议承担见上文源码调用链。小结sinon.match.symbol是 Sinon 匹配器家族中语义最清晰、用途最精准的一员它把断言收窄到必须是 Symbol 类型既接受用户自定义 Symbol也接受Symbol.iterator等 well-known Symbol同时严格拒绝字符串和普通对象。官方测试 symbol.test.js 对这四种情形做了完整覆盖而 proxy-call.js、mock-expectation.js 等源码则揭示了匹配器被统一消费的底层机制。在测试涉及 Symbol 键、协议符号或唯一标识的代码时用它能让断言更精确、意图更明确。赞分享测试开发工具【免费下载链接】sinonTest spies, stubs and mocks for JavaScript.项目地址https://gitcode.com/gh_mirrors/si/sinon点击查看免费下载相关推荐sinon.match.bool 布尔匹配器用 Sinon 精确校验 Boolean 类型参数sinon.match.bool 布尔匹配器用 Sinon 精确校验 Boolean 类型参数 sinon.match.bool 是 Sinon 匹配器Ma测试开发工具sinon.match.func 匹配器指南在 Sinon 中断言函数类型参数sinon.match.func 匹配器指南在 Sinon 中断言函数类型参数 sinon.match.func 是 Sinon 匹配器Matcher体系测试开发工具Sinon 匹配器实战sinon.match.instanceOf 精确校验对象实例类型Sinon 匹配器实战sinon.match.instanceOf 精确校验对象实例类型 导读 sinon.match.instanceOf type 是 S测试开发工具创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考