恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
Jasmine 2.5.0 发布说明全解析:spy 追踪、toEqual 深度相等与时钟模拟的关键改进
首页
资讯中心
/
Jasmine 2.5.0 发布说明全解析:spy 追踪、toEqual 深度相等与时钟模拟的关键改进
Jasmine 2.5.0 发布说明全解析:spy 追踪、toEqual 深度相等与时钟模拟的关键改进
发布时间:2026/10/4 1:48:18
测试质量保障【免费下载链接】jasmineSimple JavaScript testing framework for browsers and node.js项目地址https://gitcode.com/gh_mirrors/ja/jasmine点击查看免费下载Jasmine 2.5.0 是 JavaScript 测试框架 Jasmine 的一个里程碑式版本这一版以“修复与改进”为主线集中处理了 spy 生命周期管理、toEqual深度相等的边界情况、pretty-printer 的对象格式化以及 mock 时钟与异步回调等底层机制。本文将基于 release_notes/2.5.0.md 的官方发布说明逐项展开并结合当前仓库的 src/core 源码实现与 spec/core 测试用例帮助你理解这些变更背后的设计动机与真实行为掌握其在日常测试编写中的正确用法。版本总览一次以修复为主的稳定迭代2.5.0 的发布说明开篇即表明这是一次“包含大量修复与 pull request”的版本。从变更列表看其工作重心集中在四个方向匹配器matcher新增两个大小比较匹配器并增强toHaveBeenCalledTimes对零调用次数的支持深度相等判定toEqual修复数组附加属性、稀疏数组undefined元素、Microsoft Edge 兼容性等问题spy 体系修复继承方法上的 spy 清理、spy 被替换后再次 spy 的残留、callFake参数校验等工程与调度新增 fallback reporter、修复 mock 时钟与mockDate同步、改善异步done回调返回值等。测试代码内部的命名统一j$重命名为jasmineUnderTest发布说明中的第一个显式“Changes”条目是将 spec 中的j$重命名为jasmineUnderTest。这是一项纯粹面向仓库内部的代码整洁性改动不涉及运行时行为变化。从当前仓库看这一命名约定延续至今测试辅助文件 spec/helpers/defineJasmineUnderTest.js 与 spec/helpers/nodeDefineJasmineUnderTest.js 负责在被测环境中注入jasmineUnderTest全局变量供 spec/core 下的全部单元测试引用。它的意义在于测试代码通过一个显式的“被测对象”标识避免与运行测试宿主自身提供的jasmine全局变量混淆从而保证测试的是源码构建产物src/core而不是测试运行器自带的发行版lib/jasmine-core。对贡献者而言2.5.0 之后合并的 pull request 需要统一使用jasmineUnderTest这一命名否则会增加合并成本——这正是发布说明中“请更新任何 pull request 以简化合并”的提示背景。新增匹配器toBeGreaterThanOrEqual与toBeLessThanOrEqual2.5.0 引入了一对面向数值比较的匹配器对应 PR #1049修复 issue #1013。它们的实现极其精简核心逻辑就是一次运算符比较// 摘自 src/core/matchers/toBeGreaterThanOrEqual.js function toBeGreaterThanOrEqual() { return { compare: function(actual, expected) { return { pass: actual expected }; } }; }对应地src/core/matchers/toBeLessThanOrEqual.js 的实现为pass: actual expected。这两个匹配器接受一个Number类型的期望值用法如下expect(result).toBeGreaterThanOrEqual(25); // actual 25 时通过 expect(result).toBeLessThanOrEqual(123); // actual 123 时通过结合已有的toBeGreaterThan与toBeLessThan2.5.0 之后 Jasmine 的数值比较匹配器形成了完整的闭区间/开区间组合例如可以用toBeGreaterThanOrEqual断言边界值本身describe(数值区间断言, function() { it(支持包含边界的比较, function() { expect(100).toBeGreaterThanOrEqual(100); // 通过 expect(99).toBeGreaterThanOrEqual(100); // 失败 expect(100).toBeLessThanOrEqual(100); // 通过 expect(101).toBeLessThanOrEqual(100); // 失败 }); });toHaveBeenCalledTimes支持调用次数为 0toHaveBeenCalledTimes匹配器本身在 2.4.0 引入对应 src/core/matchers/toHaveBeenCalledTimes.js 中的since 2.4.0注释而 2.5.0 通过 PR #1048修复 issue #994补上了expected 为 0的场景。此前该匹配器在断言“从未被调用”时会失败现在可以这样写const spy jasmine.createSpy(mySpy); expect(spy).toHaveBeenCalledTimes(0); // 2.5.0 之前行为不稳定之后可靠通过从当前源码看其比较逻辑为result.pass callsCount expected其中callsCount来自actual.calls.count()src/core/CallTracker.js 中count()返回调用数组长度。当断言通过时匹配器还会把前expected次调用的verified标记置为true配合unverifiedCount()支持toHaveBeenCalledOnceWith等“已验证调用”相关匹配器的状态跟踪。失败消息中的次数措辞也做了人性化处理expected 1时输出once否则输出N times例如Expected spy mySpy to have been called once. It was called 0 times.。同时该匹配器要求参数必须是数字否则会抛出“The expected times failed is a required argument and must be a number.”的错误若 actual 不是 spy也会抛出“Expected a spy, but got ...”的错误。toEqual深度相等判定的多处修复2.5.0 对toEqual背后的MatchersUtil#eq_深度比较算法src/core/matchers/matchersUtil.js做了多个边界修复数组附加属性视为相等PR #1155此前toEqual在比较两个数组时仅比较索引位元素导致数组上挂载的自定义属性差异被忽略或误判。2.5.0 之后toEqual会比较数组上除数字索引外的附加属性。当前源码中数组分支会调用MatchersUtil.keys(a, className [object Array])而keys()对数组会过滤掉纯数字索引、只返回非数字键如字符串属性与可枚举 symbol从而实现对附加属性的深度比较expect([1, 2, 3]).toEqual([1, 2, 3]); // 通过 // 数组带附加属性的场景2.5.0 起按属性逐一深度比较稀疏数组中undefined元素的相等性修复 issue #786数组比较中a[i]与b[i]有一个不存在时会以void 0即undefined参与比较如 src/core/matchers/matchersUtil.js 中result this.eq_( i aLength ? a[i] : void 0, i bLength ? b[i] : void 0, ... ) result;2.5.0 的修复保证了无论undefined是“稀疏空洞”还是“显式赋值”在深度相等判定中都被视为等价例如[1, , 3]与[1, undefined, 3]判定为相等。这消除了稀疏数组在比较时因“元素是否存在”而出现的不一致行为。Microsoft Edge 兼容性修复PR #10412.5.0 还针对 Microsoft Edge 浏览器修正了toEqual的兼容性问题。从当前源码可以推断深度比较算法对classNameObject.prototype.toString.call分派、RegExp按source与global/multiline/ignoreCase标志比较、Date与Boolean按数值强制转换比较等分支都对不同引擎的细节有依赖2.5.0 的处理正是为了让这些分支在 Edge 的引擎实现下行为一致。pretty-printer支持构造函数带自定义toString的对象2.5.0 修复了 issue #1019PR #1099当对象的构造函数自定义了toString方法时pretty-printer 应使用该toString的输出而不是退化为打印对象结构。对应逻辑在 src/core/PrettyPrinter.js 的hasCustomToString()中它通过三个条件识别“真正的自定义 toString”function hasCustomToString(value) { try { return ( private$.isFunction(value.toString) value.toString ! Object.prototype.toString value.toString() ! Object.prototype.toString.call(value) ); } catch (e) { return true; // 自定义 toString 抛异常时也视为自定义 } }注意第三个条件专门处理了跨上下文如 iframe、web worker的对象这类对象的value.toString ! Object.prototype.toString恒成立因此还需比较调用结果是否与Object.prototype.toString.call(value)不同。如果自定义toString抛出异常pretty-printer 会输出has-invalid-toString-method占位文本避免匹配器失败消息整体崩溃。这意味着在 2.5.0 及以后当你自定义了一个带有可读toString()的类时expect失败消息会直接展示toString()的返回值大幅提升失败信息的可读性。spy 体系的修复与增强2.5.0 对 spy 的创建、清理、替换做了多项修复这些改动在 src/core/Spy.js、src/core/SpyRegistry.js、src/core/SpyStrategy.js 与 src/core/CallTracker.js 中均有对应实现。继承方法上的 spy 能正确拆除PR #1036修复 issue #737此前对原型链上继承来的方法执行spyOn后spec 结束时的拆除cleanup可能不彻底导致方法仍停留在“被 spy 替换”的状态。2.5.0 修正了这一过程确保继承方法上的 spy 在测试结束后被正确恢复为原始实现避免跨 spec 的状态污染。spy 被替换后再次 spy 的残留清理PR #1011修复 issue #1010当对一个已被 spy 的函数再次执行spyOn时旧 spy 的清理逻辑可能与新 spy 冲突。2.5.0 修复了“替换后重新 spy”场景下的正确清理顺序保证第二次 spy 基于原始函数而非前一个 spy 包装器。这一行为与“允许对已 spy 的函数再次 respy”PR #953修复 issue #931相配合2.5.0 起spyOn可以安全地对已经被 spy 过的函数再次执行 spy而不会叠加包装层。callFake的非函数参数错误消息改进PR #1059修复 issue #1016callFake要求传入函数此前传入非函数时错误信息含糊。当前实现src/core/SpyStrategy.js 的callFake会显式校验SpyStrategy.prototype.callFake function(fn) { if ( !(private$.isFunction(fn) || private$.isAsyncFunction(fn) || private$.isGeneratorFunction(fn)) ) { throw new Error(Argument passed to callFake should be a function, got fn); } this.plan fn; return this.getSpy(); };这一错误消息自 2.5.0 改进后沿用至今支持普通函数、异步函数与生成器函数。CallTracker 支持按值保存参数PR #1000修复 issue #8722.5.0 为 spy 的调用记录新增了saveArgumentsByValue能力默认情况下 spy 记录的是参数的引用如果调用后参数对象被修改calls.allArgs()取到的将是被修改后的值。开启按值保存后每次调用都会用克隆函数对参数做快照。当前实现在 src/core/CallTracker.js 中this.track function(context) { if (opts.cloneArgs) { context.args opts.argsCloner(context.args); } calls.push(context); }; this.saveArgumentsByValue function(argsCloner private$.util.cloneArgs) { opts.cloneArgs true; opts.argsCloner argsCloner; };saveArgumentsByValue默认使用浅克隆private$.util.cloneArgs也接受自定义克隆函数。典型场景是异步回调或事件处理器中参数后续被复用的对象const spy jasmine.createSpy(handler); spy.and.callFake(function(obj) { /* ... */ }); spy.calls.saveArgumentsByValue(); const payload { count: 1 }; spy(payload); payload.count 2; expect(spy.calls.first().args[0].count).toBe(1); // 记录的是调用时的快照spyOn相关的其它细节2.5.0 移除了不再使用的runnableLookupTablePR #1129这是 spy/suite 查找表的内部清理移除了 topSuite 构造queueRunner的多余参数PR #1006属于内部 API 精简。异步与调度机制改进done回调现在返回nullPR #1062修复 issue #992异步 spec 与beforeEach/afterEach中使用的done回调在 2.5.0 之后调用时返回null。此前done()的返回值在Promise化的 QueueRunner 中可能被误当作 promise 处理造成未捕获的 promise 警告或行为异常。这一改动让done的返回值为确定性值null避免与 promise 返回路径混淆。相关调度逻辑见 src/core/QueueRunner.js。允许在全局beforeAll/afterAll中使用 expectation修复 issue #8112.5.0 之前在**根级非 describe 内**的beforeAll/afterAll中书写expect会因执行上下文不完整而出错。此修复使全局钩子中的断言得到正常处理例如beforeAll(function() { expect(globalSetupState.ready).toBe(true); }); describe(套件, function() { /* ... */ });fallback reporter 支持PR #10092.5.0 新增provideFallbackReporter机制当没有任何 reporter 被显式添加时fallback reporter 会被自动挂载保证结果仍能被输出。当前实现在 src/core/ReportDispatcher.js 中this.provideFallbackReporter function(reporter) { fallbackReporter reporter; }; function dispatch(method, event) { if (reporters.length 0 fallbackReporter ! null) { reporters.push(fallbackReporter); } // ...通过 QueueRunner 串行派发事件 }可以看到fallback 仅在reporters为空时才生效且一旦有显式 reporter 加入便不再介入。事件派发本身通过runQueue串行执行并返回 Promise支持异步 reporter 回调超过一次调用done会触发 onLateError。DelayedFunctionScheduler 同步更新 mockDatePR #980修复 issue #915mock 时钟jasmine.clock()的核心调度器 src/core/DelayedFunctionScheduler.js 在 2.5.0 中修复了与mockDate的联动当tick()推进调度器内部时间currentTime_时会通过tickDate回调同步推进jasmine.clock().mockDate()设置的模拟日期。从源码看this.tick function(millis, tickDate) { millis millis || 0; const endTime this.currentTime_ millis; this.runScheduledFunctions_(endTime, tickDate); };在runScheduledFunctions_中每次时间前进都会调用tickDate(newCurrentTime - this.currentTime_)确保Date的模拟值与定时器调度保持一致。这样在clock.mockDate()生效期间执行clock.tick(...)通过new Date()读取到的时间也会同步前进避免“定时器触发了但日期没变”的错位。此外该调度器还明确拒绝字符串形式的定时器回调“The mock clock does not support the eval form of setTimeout and setInterval”这一约束与 2.5.0 时代对安全性的强化一脉相承。describe错误消息不再假定多余参数是done修复 issue #896此前在describe中误传多余参数时错误消息会把参数提示为done回调的误用2.5.0 改为更中性的描述避免误导排查方向。环境与工程化改进2.5.0 还包含一批与运行环境、构建链路相关的改动变更说明仓库中的对应证据Electron 环境修复PR #1079修复 issue #964修正 Jasmine 在 Electron 渲染进程中的初始化问题当前构建入口 src/boot/boot.js、src/boot/jasmine-core.jsIE 测试说明PR #1170新增在 IE 中运行测试的指引测试辅助 spec/helpers/BrowserFlags.js 承载浏览器差异处理gulp-jasmine-browser 链接修复 issue #1089README 补充浏览器自动化运行方式浏览器测试配置见 spec/support/jasmine-browser.jsExclude lib 目录修复 issue #1171CodeClimate 分析排除lib/构建产物目录发行产物目录 lib/jasmine-core 为构建生成devDependencies 更新PR #1162升级依赖并修复连带问题当前 package.json 的devDependencies已演进至 eslint 9 prettier 时代Travis 上 Ruby 版本升级PR #1152使 rack 可安装保障 CI 构建CI 脚本见 spec/support/ci.js新增.editorconfigPR #1058修复 issue #1057统一跨编辑器缩进与换行风格仓库至今保留该文件的编码约定License 年份更新至 2016PR #1021版权年份范围滚动见 LICENSE随机种子参数在 “run all” 链接中持久化PR #990随机执行顺序参数随链接保留相关逻辑位于 src/html/QueryString.js 的 URL 参数解析其中“随机参数持久化”值得留意Jasmine 支持--random随机化 spec 执行顺序randomize配置2.5.0 保证在 HTML 报告器的 “run all” 重跑链接中保留随机种子参数便于复现随机顺序下的失败。小结2.5.0 的遗产与后续演进回看 2.5.0它虽然以“修复为主”但这些修复奠定了后续版本多项核心能力的基石spy 生命周期的完整治理继承方法、替换 respy、按值保存参数直接支撑了 3.x 中withArgs多策略、toHaveBeenCalledOnceWith等能力的可靠运行toEqual深度相等的边界补全附加属性、稀疏数组、跨引擎一致性至今仍是 src/core/matchers/matchersUtil.js 比较算法的基本盘pretty-printer 的自定义toString支持开启了对象格式化可扩展性的先河后续版本又在其上叠加了自定义对象格式化器custom object formatters能力fallback reporter 与 QueueRunner 的异步化为报告器生态jasmine-reporters、jasmine-browser-runner铺平了道路。如果你正在升级或阅读 Jasmine 源码2.5.0 是一个很好的“分水岭”在此之后spy 与深度相等两条主线的行为定义趋于稳定后续版本的变更大多是在 2.5.0 建立的语义之上做增量扩展。对测试编写者而言2.5.0 引入的toBeGreaterThanOrEqual/toBeLessThanOrEqual、零次调用的toHaveBeenCalledTimes、saveArgumentsByValue与全局钩子断言都是至今仍高频使用的 API值得熟练掌握。赞分享测试质量保障【免费下载链接】jasmineSimple JavaScript testing framework for browsers and node.js项目地址https://gitcode.com/gh_mirrors/ja/jasmine点击查看免费下载相关推荐NumPy 1.11.1 发布说明深度解析21 项关键 Bug 修复与构建改进全梳理NumPy 1.11.1 发布说明深度解析21 项关键 Bug 修复与构建改进全梳理 导读本文以 NumPy 1.11.1 Release Notes 为骨科学计算数据分析FoundationDB 7.0 版本发布说明深度解读Redwood 存储引擎、GRV Proxy 与 TSS 等关键演进FoundationDB 7.0 版本发布说明深度解读Redwood 存储引擎、GRV Proxy 与 TSS 等关键演进 本篇指南围绕 Foundation分布式数据库KV存储数据库后端OpenFace 版本发布说明深度解读从 0.1.0 到 0.2.1 的关键改进与源码级验证OpenFace 版本发布说明深度解读从 0.1.0 到 0.2.1 的关键改进与源码级验证 OpenFace 是基于深度神经网络的开源人脸识别项目其 do人工智能计算机视觉深度学习上一篇高性能分布式缓存系统设计基于oneTBB concurrent_hash_map的实战指南下一篇4步搞定简历导出双格式全攻略创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考