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

Sinon 断言指南:`assert.called`——验证 spy、stub 与 fake 至少被调用过一次

发布时间:2026/9/24 16:26:25 来源:云帆数科 栏目:资讯中心
Sinon 断言指南:`assert.called`——验证 spy、stub 与 fake 至少被调用过一次
测试开发工具【免费下载链接】sinonTest spies, stubs and mocks for JavaScript.项目地址https://gitcode.com/gh_mirrors/si/sinon点击查看免费下载assert.called(spy)是 Sinon 内置断言 API 中最基础的断言之一只要传入的fake、spy或stub在测试期间至少被调用过一次断言即通过否则抛出一个带有详细描述信息的AssertError。本文基于当前仓库中 called.md 文档并结合 assert.js 源码与对应的 单元测试从使用方式、错误消息、底层实现到相关断言家族完整讲解这一断言在测试中的定位与实战用法。断言签名与语义assert.called(spy);语义非常直接校验目标函数是否被调用过至少一次。只要调用次数 ≥ 1断言通过调用次数为 0断言失败。它适用于 Sinon 三类测试替身test doublespy包装原始函数或独立存在记录调用信息但不改变行为stub可预设行为的替身同样记录调用信息fake更现代、更轻量的独立替身与 spy 拥有相同的调用记录能力。因此凡是能记录调用历史的 Sinon 代理对象都可以作为assert.called的参数。快速上手在 ESM 环境下从sinon包导入 API 后即可使用参见 called.md 中的基础示例import * as sinon from sinon; const spy sinon.spy(); // 此时 spy 尚未被调用断言失败 sinon.assert.called(spy); // Error [AssertError]: expected spy to have been called at least once but was never called spy(); // 调用一次 // 现在断言通过不产生任何异常 sinon.assert.called(spy);关键行为有两点失败即抛错断言失败时抛出的异常name为AssertError见 assert.js 中fail的实现可以直接被测试框架捕获并判定用例失败成功静默断言通过时不返回任何值、不产生异常配合assert.pass的内部机制静默返回见 assert.js。在测试框架中使用仓库为每个文档 API 都配套了可运行的测试用例。assert.called对应的测试位于 docs/tests/docs/assertions/api/called.test.js使用tap编写覆盖了调用后通过与未调用即失败两个方向import tap from tap; import * as sinon from sinon; tap.test(assert.called - passes when spy was called, (t) { const spy sinon.spy(); spy(); t.doesNotThrow(() { sinon.assert.called(spy); }, assertion should pass); t.end(); }); tap.test(assert.called - fails when spy was not called, (t) { const spy sinon.spy(); t.throws( () sinon.assert.called(spy), /expected spy to have been called at least once but was never called/, assertion should fail with descriptive message ); t.end(); });这套测试同时也验证了两件事失败消息的文本是稳定可匹配的契约正则中直接匹配了错误文案以及断言通过时确实不会抛出异常。在实际的 Jest / Mocha / Vitest 项目中可直接把断言放进it/test回调中失败时框架会自动收集AssertError。失败时的错误消息是如何生成的assert.called的默认失败消息模板定义在 assert.jsmirrorPropAsAssertion( called, expected %n to have been called at least once but was never called, );其中%n是格式化占位符由 spy-formatters.js 中的n处理器替换为spyInstance.toString()即 spy 的名称描述如spy。消息组装完成后通过(fake.printf || fake.proxy.printf).apply(...)渲染出来见 assert.js最终抛出。与它同族的断言还有calledOnce、calledTwice、calledThrice它们会额外用%c占位符输出实际的调用次数英文描述如once、twice、thrice由timesInWords生成例如expected spy to be called once but was called twicecalledOnce 失败时也就是说assert.called的失败消息聚焦于从未被调用这一种失败形态而次数敏感型断言如calledOnce则能进一步告诉你实际被调用了几次。源码视角assert.called的底层实现assert.called并不是手写的一个独立函数而是通过mirrorPropAsAssertion这个工厂函数批量生成的见 assert.js。其执行流程如下校验参数verifyIsStub(fake)assert.js先确认传入的是有效的 Sinon 代理对象——若传入null会报fake is not a spy若对象没有getCall方法会报fake is not stubbed校验参数个数verifyIsValidAssertionassert.js规定called不接受额外参数多传参数会直接报错called takes 1 argument but was called with N arguments读取布尔属性对called而言meth未提供函数因此直接读取fake.called这个布尔属性assert.js判定与输出failed为真时调用failAssertion渲染并抛出AssertError否则调用assert.pass静默通过。fake.called属性由谁维护assert.called读到的called布尔属性是 Sinon 代理对象在每次被调用时由incrementCallCount同步更新的见 proxy-call-util.jsexport function incrementCallCount(proxy) { proxy.called true; proxy.callCount 1; proxy.notCalled false; proxy.calledOnce proxy.callCount 1; proxy.calledTwice proxy.callCount 2; proxy.calledThrice proxy.callCount 3; }代理在初始化时called被置为false见 proxy.js此后每调用一次就置true并递增callCount。因此assert.called本质上是对spy.called true这一状态的断言封装——你也可以在代码里直接读取spy.called做条件判断但用assert.called能获得统一、描述清晰的失败消息。与相关断言的组合使用assert.called只回答有没有被调用过这一个问题。当测试需要更强的约束时可以按需组合 Assertions API 家族中的其他成员完整列表见 docs/concepts/assertions/api/场景推荐断言语义至少调用一次assert.called本次讨论的断言一次都没调用assert.notCalled与called互斥失败消息为expected spy to not have been called but was called %c%C恰好调用一次assert.calledOnce失败时会输出实际次数恰好两次 / 三次assert.calledTwice/assert.calledThrice次数精确断言精确参数assert.calledWith/assert.calledWithExactly结合参数校验以 matcher 匹配参数assert.calledWithMatch结合 matchers 使用精确调用次数assert.callCount断言具体次数数值一个常见组合是先确认被调用再确认调用参数const spy sinon.spy(); doWork(spy); sinon.assert.called(spy); // 1. 至少调用了一次 sinon.assert.calledWith(spy, key, 42); // 2. 且最后一次调用参数正确注意assert.called本身不校验参数、不校验this上下文、不校验调用次数上限这些分别由calledWith、calledOn、calledOnce等断言承担按需组合即可。进阶实践与注意事项1. 包装真实方法后再断言除了独立的sinon.spy()最常见的是对真实对象方法做包装验证某个依赖是否被触发const service { save(data) { /* 真实逻辑 */ } }; const saveSpy sinon.spy(service, save); service.save({ id: 1 }); sinon.assert.called(saveSpy); saveSpy.restore(); // 记得恢复原始方法2. 与 stub 一起使用stub 同样记录调用信息因此assert.called也可用于验证某个被替换的依赖是否被调起const stub sinon.stub().returns(42); compute(stub); sinon.assert.called(stub);3. 配合assert.expose批量暴露到测试对象如果希望断言以更贴近阅读习惯的形式出现可以使用assert.expose把整个断言对象批量挂载到目标对象上见 assert.js 的expose实现支持prefix与includeFail选项。例如挂到全局后即可写assert.called(spy)而无需每次sinon.assert.前缀。4. 在沙箱sandbox中使用配合sinon.createSandbox()可以把替身与断言放在同一作用域内统一恢复const sandbox sinon.createSandbox(); const spy sandbox.spy(); run(); sandbox.assert.called(spy); sandbox.restore();5. 注意事项只验证至少一次若测试要求恰好一次请改用calledOnce否则调用两次时assert.called依然静默通过可能掩盖回归不接受额外参数assert.called(spy, somethingElse)会直接抛错而非忽略多余参数参数必须是 Sinon 代理普通函数或非 spy 对象会触发fake is not a spy/fake is not stubbed等前置校验错误错误类型为AssertError断言失败抛出的是名为AssertError的普通Error可被任何主流测试框架识别若开启了shouldLimitAssertionLogs选项长日志会被截断到assertionLogLimit默认 10K见 assert.js。小结assert.called是 Sinon 断言体系里最朴素、最常用的一环它把目标替身是否被调用过这一高频测试诉求封装成一个失败消息清晰、行为可预期的断言。理解它的语义边界只验证至少一次、底层数据来源proxy.called与incrementCallCount以及同族断言calledOnce、notCalled、calledWith等的分工能帮助你在编写单元测试时快速选出正确的断言写出既严谨又易读的测试代码。更多断言方法与使用示例可继续阅读 Assertions API 索引 及仓库中的 断言测试目录。赞分享测试开发工具【免费下载链接】sinonTest spies, stubs and mocks for JavaScript.项目地址https://gitcode.com/gh_mirrors/si/sinon点击查看免费下载相关推荐notebooklm-py 的 Android gRPC 能力与签名取证体系APK 静态提取、Web 端签名推断与移动端实证验证notebooklm py 的 Android gRPC 能力与签名取证体系APK 静态提取、Web 端签名推断与移动端实证验证 本文解析 notebookl测试开发工具Sinon assert.calledThrice 详解精确断言 spy/fake/stub 恰好被调用三次Sinon assert.calledThrice 详解精确断言 spy/fake/stub 恰好被调用三次 sinon.assert.calledThric测试开发工具Sinon assert.alwaysCalledWith 完全指南验证 fake/spy/stub 每次调用参数一致Sinon assert.alwaysCalledWith 完全指南验证 fake/spy/stub 每次调用参数一致 sinon.assert.always测试开发工具上一篇如何在Krita中3分钟实现AI绘画免费开源的终极创作神器下一篇3个资源捕获痛点猫抓浏览器扩展如何重新定义网页媒体下载体验创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关推荐

Swagger Codegen 生成的 Jersey2 Java8 客户端:StoreApi 订单与库存接口完整使用指南
Swagger Codegen 生成的 Jersey2 Java8 客户端:StoreApi 订单与库存接口完整使用指南

开发工具代码生成API设计 【免费下载链接】swagger-codegen swagger-codegen contains a template-driven engine to generate documentation, API clients and server stubs in different languages by parsing your OpenAPI / Swagger definition. 项目地址: http… · 2026/9/24 16:26:25

ARA Research Manager 会话协议深度解析:让 AI 研究 Agent 拥有可审计的跨会话记忆
ARA Research Manager 会话协议深度解析:让 AI 研究 Agent 拥有可审计的跨会话记忆

AI 技能人工智能大模型深度学习 【免费下载链接】AI-Research-SKILLs Comprehensive open-source library of AI research and engineering skills for any AI model. Package the skills and your claude code/codex/gemini agent will be an AI research agent with full hor… · 2026/9/24 16:26:25

ToastFish:把 Windows 通知栏变成免费背单词神器,摸鱼 3 分钟入门
ToastFish:把 Windows 通知栏变成免费背单词神器,摸鱼 3 分钟入门

ToastFish:把 Windows 通知栏变成免费背单词神器,摸鱼 3 分钟入门 【免费下载链接】ToastFish 一个利用摸鱼时间背单词的软件。 项目地址: https://gitcode.com/GitHub_Trending/to/ToastFish 如果你也常想背单词,却怕屏幕上明晃晃的背… · 2026/9/24 16:26:25

【Dify】YouTube全自动内容生成与多平台分发应用
【Dify】YouTube全自动内容生成与多平台分发应用

自媒体视频内容的生产和分发,已成为内容创业与个人品牌塑造的重要途径。高效的视频自动化处理工具,能够显著提升内容制作与运营的效率。 本文聚焦于YouTube及多平台自媒体场景,介绍一个覆盖从素材导入、音频转写、语义分析、文案生成、分段整理到成品分发的全流程工作流。通… · 2026/9/24 17:04:43

Kubernetes 云原生 CI/CD 落地实践:从 DevOps 到 GitOps 的持续构建与发布指南
Kubernetes 云原生 CI/CD 落地实践:从 DevOps 到 GitOps 的持续构建与发布指南

教程云原生容器编排 【免费下载链接】kubernetes-handbook Kubernetes 架构与生态:从云原生到 AI 原生基础设施的构建指南 项目地址: https://gitcode.com/gh_mirrors/ku/kubernetes-handbook 点击查看 免费下载 导读 本文以 kubernetes-handbook 仓库… · 2026/9/24 17:04:31

Presto Release 0.178 版本解读:内存治理、SQL 能力扩展与 Connector 稳定性改进
Presto Release 0.178 版本解读:内存治理、SQL 能力扩展与 Connector 稳定性改进

大数据数据库后端 【免费下载链接】presto The official home of the Presto distributed SQL query engine for big data 项目地址: https://gitcode.com/gh_mirrors/pre/presto 点击查看 免费下载 本文以 Presto 官方发布说明 release-0.178.rst 为骨架&#xff… · 2026/9/24 17:04:31

handy4cj邮箱与手机号校验实战:RFC 2822标准验证背后的简单原理
handy4cj邮箱与手机号校验实战:RFC 2822标准验证背后的简单原理

handy4cj邮箱与手机号校验实战:RFC 2822标准验证背后的简单原理 【免费下载链接】handy4cj 项目地址: https://gitcode.com/Cangjie-SIG/handy4cj handy4cj 是一个基于仓颉语言的实用工具库,内置 checkEmail 邮箱校验函数(严格遵循 R… · 2026/9/24 17:04:25

Prisma 服务配置完全指南:从 `prisma.yml` 到数据模型部署(prisma1 仓库 1.3 参考文档)
Prisma 服务配置完全指南:从 `prisma.yml` 到数据模型部署(prisma1 仓库 1.3 参考文档)

Prisma 服务配置完全指南:从 prisma.yml 到数据模型部署(prisma1 仓库 1.3 参考文档) 【免费下载链接】prisma1 💾 Database Tools incl. ORM, Migrations and Admin UI (Postgres, MySQL & MongoDB) [deprecated] 项目地址… · 2026/9/24 17:04:25

大麦抢票自动化指南:如何从环境自检到订单提交,3分钟跑通全流程
大麦抢票自动化指南:如何从环境自检到订单提交,3分钟跑通全流程

大麦抢票自动化指南:如何从环境自检到订单提交,3分钟跑通全流程 【免费下载链接】ticket-purchase 大麦自动抢票,支持人员、城市、日期场次、价格选择 项目地址: https://gitcode.com/GitHub_Trending/ti/ticket-purchase 本文基于开源… · 2026/9/24 17:04:24

基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程
基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程

简介:这是一套面向计算机、人工智能、自动化等专业学生与教师的毕业设计级项目资源,围绕YOLOv8实现渔船作业监控系统,可用于毕设、课程设计、大作业或项目立项演示。压缩包共97个文件,约24.21MB,以70个Python源码文件为… · 2026/9/24 0:00:13

1D-CNN时间序列建模实战:从Conv1d原理到工业落地
1D-CNN时间序列建模实战:从Conv1d原理到工业落地

简介:面向时间序列数据建模的一维卷积神经网络完整实现,适合深度学习入门者及需要快速验证时序模型的研究者,能够从音频、文本、传感器或股价等序列中挖掘局部特征与时间依赖。压缩包体积很小,只有3KB,内含3个Python脚… · 2026/9/24 0:00:26

柔软的L:汉语语流中被忽视的舌肌张力控制
柔软的L:汉语语流中被忽视的舌肌张力控制

1. 这个“L”不是字母表里的L,而是舌尖上的L最近在几个方言群和语音教学社群里,反复看到有人发一句:“也说字母L:柔软的长舌”。初看以为是英语发音课笔记,点开才发现全是方言爱好者、播音系学生、语言康复师甚至戏曲演… · 2026/9/24 0:00:44

了解更多?预约专属演示

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

企业微信二维码