Enzyme ReactWrapper.someWhere() 详解:用谓词函数断言“任一节点满足条件”
测试前端【免费下载链接】enzymeJavaScript Testing utilities for React项目地址https://gitcode.com/gh_mirrors/en/enzyme点击查看免费下载.someWhere(predicate)是 Enzyme 为ReactWrapper提供的集合级断言方法它接收一个谓词函数遍历当前 wrapper 中包装的所有节点只要至少有一个节点满足条件即返回true。本文以 someWhere 官方文档 为骨架结合仓库源码 ReactWrapper.js 与共享测试 someWhere.jsx 的实现细节帮助你掌握这一方法的参数语义、返回值、典型用法以及它与some、every、everyWhere三个兄弟方法之间的区别与配合方式。方法签名与语义.someWhere(fn) BooleansomeWhere与内置数组方法Array.prototype.some语义一致对 wrapper 中的每一个节点逐一执行谓词函数只要其中任意一个节点的谓词返回真值someWhere就返回true只有所有节点都未通过谓词时才返回false。它回答的核心问题是“当前这批节点里是否存在满足某某条件的节点”从 ReactWrapper.js 的实现可以清晰看到这一点someWhere(predicate) { return this.getNodesInternal().some((n, i) predicate.call(this, this.wrap(n), i)); }getNodesInternal()返回 wrapper 内部保存的节点数组见 getNodesInternal 定义即this[NODES]数组的.some()负责短路求值一旦某个节点命中即停止遍历并返回true每个原始节点n会先经this.wrap(n)重新包装成ReactWrapper后再交给谓词因此你在谓词里拿到的是完整的 ReactWrapper 实例可以继续调用.hasClass()、.prop()、.text()等任意 API。wrap方法定义见 ReactWrapper.js若节点已是ReactWrapper则直接复用否则新建实例。参数说明someWhere仅接受一个参数参数类型说明predicateReactWrapper Boolean谓词函数接收被包装后的单个节点ReactWrapper作为第一个参数索引i作为第二个参数返回布尔值真值亦可谓词内部的this指向调用someWhere的 wrapper 本身源码中通过predicate.call(this, ...)绑定这一点与forEach、map、reduce等方法保持一致便于在需要时在谓词中访问外层 wrapper 的上下文。返回值返回Booleantrue当前 wrapper 中至少一个节点通过谓词false没有任何节点通过谓词或当前 wrapper 不包含任何节点空 wrapper 的.some()恒为false。使用示例官方文档给出了一个直接可运行的断言示例其中wrapper.find(.foo)得到包含 3 个div节点的 wrapper再用.someWhere对这批节点逐一进行hasClass判断const wrapper mount(( div div classNamefoo qoo / div classNamefoo boo / div classNamefoo hoo / /div )); expect(wrapper.find(.foo).someWhere((n) n.hasClass(qoo))).to.equal(true); expect(wrapper.find(.foo).someWhere((n) n.hasClass(foo))).to.equal(true); expect(wrapper.find(.foo).someWhere((n) n.hasClass(bar))).to.equal(false);执行逻辑推演wrapper.find(.foo)命中 3 个节点foo qoo、foo boo、foo hoo(n) n.hasClass(qoo)只有第一个节点命中.some()短路返回true(n) n.hasClass(foo)所有节点都含foo类任意一个即返回true(n) n.hasClass(bar)没有任何节点含bar类返回false。这三个断言用例与仓库共享测试 someWhere.jsx 中的用例完全一致该测试同时被ReactWrapper-spec与ShallowWrapper-spec复用验证了两种 wrapper 上的行为一致性。谓词的组合用法由于谓词拿到的是完整ReactWrapper你可以用逻辑运算符组合出更复杂的条件例如同时满足多个特征、或满足任一特征// 是否存在同时含 active 且被禁用的按钮 expect(wrapper.find(button).someWhere((n) n.hasClass(active) n.prop(disabled))).to.equal(true); // 是否存在处于 loading 或 error 状态的区域 expect(wrapper.find(.panel).someWhere((n) n.hasClass(loading) || n.hasClass(error))).to.equal(true);结合索引参数i还可以做位置相关的判断例如“是否存在第一个元素恰好是标题”expect(wrapper.find(li).someWhere((n, i) i 0 n.text() Title)).to.equal(true);与 some / every / everyWhere 的关系官方文档在 “Related Methods” 中列出了三个关联方法它们的核心差异在于判定依据是选择器还是谓词以及判定粒度是“存在任一”还是“全部满足”方法判定依据语义典型返回true的条件.some(selector)EnzymeSelector选择器任一节点匹配选择器至少一个节点匹配.someWhere(predicate)谓词函数任一节点通过谓词至少一个节点通过.every(selector)EnzymeSelector选择器所有节点匹配选择器全部节点匹配.everyWhere(predicate)谓词函数所有节点通过谓词全部节点通过选择器版 vs 谓词版some(selector)/every(selector)内部通过buildPredicate(selector)把选择器编译为谓词再交给数组方法见 some 实现适合规则简单的类名、标签、属性匹配someWhere/everyWhere则直接接收函数能够表达选择器难以覆盖的逻辑判断跨 prop 条件组合、文本内容匹配、索引判断等灵活性更高。两种方式在空 wrapper 上的语义也一致some/someWhere返回falseevery/everyWhere返回true空集的全称量词。someWhere vs everyWhere二者源码结构完全相同.some与.every互换是“存在量词”与“全称量词”的一对互补方法everyWhere(predicate) { return this.getNodesInternal().every((n, i) predicate.call(this, this.wrap(n), i)); }见 everyWhere 实现。实际测试中“至少一个失败”等价于“everyWhere(取反条件)为false”但直接使用someWhere表达意图更直白。注意与some(selector)在根节点上调用会抛出ReactWrapper::some() can not be called on the root错误不同someWhere没有这一限制对根节点调用同样是合法的因为它以谓词函数而非选择器为判定依据。ShallowWrapper 上的等价用法someWhere同样存在于ShallowWrapper浅渲染其文档见 ShallowWrapper.someWhere唯一区别是谓词参数类型为ShallowWrapper Boolean示例中只需把mount换成shallowconst wrapper shallow(( div div classNamefoo qoo / div classNamefoo boo / div classNamefoo hoo / /div )); expect(wrapper.find(.foo).someWhere((n) n.hasClass(qoo))).to.equal(true); expect(wrapper.find(.foo).someWhere((n) n.hasClass(foo))).to.equal(true); expect(wrapper.find(.foo).someWhere((n) n.hasClass(bar))).to.equal(false);从 ShallowWrapper.js 可以看到其实现与ReactWrapper完全同构。因此无论在mount完整渲染适用于与 DOM 交互的集成测试还是shallow浅渲染适用于组件单元测试场景下someWhere的 API 形态和断言语义保持一致可以无缝切换。若需要了解mount与shallow各自的适用场景可参考 api/mount 与 api/shallow。小结.someWhere(predicate)是 Enzyme 断言体系中“存在性 自定义逻辑”的组合它借力原生数组的.some()实现短路求值把每个节点包装回ReactWrapper交给谓词因此可以自由组合hasClass、prop、text、索引等多种判断维度。搭配.everyWhere可以覆盖“任一”与“全部”两类集合断言需求当判断规则足够简单时some(selector)则是更轻量的选择。掌握这组方法就能用简洁、可读的断言表达对多节点渲染结果的各种预期。赞分享测试前端【免费下载链接】enzymeJavaScript Testing utilities for React项目地址https://gitcode.com/gh_mirrors/en/enzyme点击查看免费下载相关推荐es-toolkit/compat overSome把多个条件函数合成一个任一满足谓词的 Lodash 兼容指南es toolkit/compat overSome把多个条件函数合成一个任一满足谓词的 Lodash 兼容指南 本篇技术指南围绕 es toolkit前端后端lo 库 CountBy 函数详解基于 Go 泛型谓词的条件计数lo 库 CountBy 函数详解基于 Go 泛型谓词的条件计数 CountBy 是 samber/lo一个基于 Go 1.18 泛型的 Lodash 风后端TBOOX/TBOX谓词函数条件判断与过滤的逻辑封装TBOOX/TBOX谓词函数条件判断与过滤的逻辑封装 概述 在C语言开发中条件判断和元素过滤是日常编程中频繁遇到的需求。TBOX作为一款跨平台的C语言基础库后端上一篇告别表单错误AppSmith JSON表单的智能验证机制详解下一篇从源码到部署深度解析Letterpress的Markdown解析与HTML生成机制创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考