恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
enzyme 中 `.not(selector)` 方法详解:如何过滤出所有不匹配选择器的节点
首页
资讯中心
/
enzyme 中 `.not(selector)` 方法详解:如何过滤出所有不匹配选择器的节点
enzyme 中 `.not(selector)` 方法详解:如何过滤出所有不匹配选择器的节点
发布时间:2026/9/20 13:15:36
测试前端【免费下载链接】enzymeJavaScript Testing utilities for React项目地址https://gitcode.com/gh_mirrors/en/enzyme点击查看免费下载导读.not(selector)是 enzyme 为ReactWrapper由mount()产生与ShallowWrapper由shallow()产生提供的筛选方法它返回一个仅包含当前 wrapper 中不匹配指定选择器的节点的新 wrapper本质上是.filter(selector)的逻辑取反。本文以 docs/api/ReactWrapper/not.md 为核心结合仓库源码与共享测试用例完整讲解其签名、参数类型、返回值、底层实现原理与实战用法帮助你在测试断言中熟练运用排除法筛选节点。方法签名与核心语义.not(selector) ReactWrapper // mount 渲染后的完整 DOM 树 .not(selector) ShallowWrapper // shallow 渲染的单层组件树官方文档给出的定义非常精炼Returns a new wrapper with only the nodes of the current wrapper that dont match the provided selector.This method is effectively the negation or inverse offilter.翻译过来就是返回一个新 wrapper其中只保留当前 wrapper 中不匹配所提供选择器的节点该方法本质上是filter的否定或逆操作。换言之下面两条语句在逻辑上是等价的wrapper.not(selector) // 等价于 wrapper.filter((node) !matches(node, selector))它非常适合从一组节点中剔除某几类节点的场景例如找出所有带foo类但不带bar类的元素、找出所有div以外的元素等。参数Arguments方法只有一个参数参数类型说明selectorEnzymeSelector用于匹配节点的选择器EnzymeSelector在 enzyme 中一共支持三类形态这一事实可从 packages/enzyme/src/selectors.js 的buildPredicate实现中得到印证字符串形式的简单 CSS 选择器如.foo、div、[data-foobar]、#id。注意not底层复用的buildPredicate只支持简单选择器传入包含组合符如div span、.a .b的复杂 CSS 选择器会抛出TypeError: This method does not support complex CSS selectors。组件构造函数Component Constructor用于按组件类型筛选例如not(MyComponent)。非空属性对象props object键值对作为要匹配的 props例如not({ disabled: true })。若对象中包含undefined值会抛出TypeError: Enzyme::Props cant have \undefined values. Try using findWhere() instead.。返回值Returns对于ReactWrapper返回ReactWrapper——一个包装了过滤后节点的新 wrapper。对于ShallowWrapper返回ShallowWrapper——语义相同类型对应。返回的是新的wrapper 实例原 wrapper 不会被修改因此可以继续链式调用其他方法。底层实现原理源码级解析虽然文档很短但源码实现非常清晰值得展开。.not在ReactWrapper与ShallowWrapper两个类中的实现完全一致ReactWrapper 实现packages/enzyme/src/ReactWrapper.js/** * Returns a new wrapper instance with only the nodes of the current wrapper that did not match * the provided selector. Essentially the inverse of filter. * * param {EnzymeSelector} selector * returns {ReactWrapper} */ not(selector) { const predicate buildPredicate(selector); return filterWhereUnwrapped(this, (n) !predicate(n)); }ShallowWrapper 实现packages/enzyme/src/ShallowWrapper.jsnot(selector) { const predicate buildPredicate(selector); return filterWhereUnwrapped(this, (n) !predicate(n)); }整个流程可拆解为三步构建谓词函数buildPredicate(selector)位于 packages/enzyme/src/selectors.js负责把字符串选择器解析为 tokensafelyGenerateTokens、按组件类型或 props 对象分别生成对应的节点匹配函数nodeMatchesToken/matchesElementType/nodeMatchesObjectProps。取反(n) !predicate(n)把匹配选择器的谓词翻转成不匹配选择器的谓词——这正是not与filter的唯一差别其余逻辑 100% 复用。过滤并重新包装调用filterWhereUnwrappedReactWrapper.jsfunction filterWhereUnwrapped(wrapper, predicate) { return wrapper.wrap(wrapper.getNodesInternal().filter(predicate).filter(Boolean)); }getNodesInternal()取出当前 wrapper 内部持有的全部节点数组.filter(predicate)执行筛选.filter(Boolean)剔除因 React 条件渲染可能残留的null/false空节点最后通过wrapper.wrap(...)生成并返回一个新的 wrapper。这一实现同时解释了文档中Returns a new wrapper的语义原始 wrapper 的节点列表不会受影响。使用示例文档原始示例以mount为例ReactWrapperconst wrapper mount(MyComponent /); expect(wrapper.find(.foo).not(.bar)).to.have.lengthOf(1);含义先find(.foo)找出所有带foo类的节点再.not(.bar)从中剔除带bar类的节点最终断言剩下的节点数量为 1。官方共享测试用例仓库中 packages/enzyme-test-suite/test/shared/methods/not.jsx 提供了更丰富的验证场景该测试文件同时被ReactWrapper-spec与ShallowWrapper-spec复用因此下列断言对两种 wrapper 都成立const wrapper Wrap(( div div classNamefoo bar baz / div classNamefoo / div classNamebar baz / div classNamebaz / div classNamefoo bar / /div )); // 5 个节点中带 .foo 的有 3 个foo bar baz、foo、foo bar其中带 .bar 的有 2 个 // 剔除后剩下 1 个纯 .foo 节点 expect(wrapper.find(.foo).not(.bar)).to.have.lengthOf(1); // 带 .baz 的有 3 个foo bar baz、bar baz、baz其中带 .foo 的有 1 个 // 剔除后剩下 2 个 expect(wrapper.find(.baz).not(.foo)).to.have.lengthOf(2); // 带 .foo 的 3 个节点全部是 div剔除所有 div 后为 0 个 expect(wrapper.find(.foo).not(div)).to.have.lengthOf(0);更多实战写法shallow场景ShallowWrapper与mount完全同构const wrapper shallow(MyComponent /); expect(wrapper.find(.foo).not(.bar)).to.have.lengthOf(1);按组件类型过滤适用于浅渲染下的自定义组件const wrapper shallow( div Foo / Foo / Bar / /div ); expect(wrapper.find(Foo)).to.have.lengthOf(2); expect(wrapper.find(div).not(Foo)).to.have.lengthOf(1); // 只剩根 div按 props 对象过滤const wrapper mount( ul li disableda/li lib/li li disabledc/li /ul ); // 找出所有未禁用没有 disabled 属性的 li expect(wrapper.find(li).not({ disabled: true })).to.have.lengthOf(1);组合断言场景——包含 A 但不包含 B的经典写法const wrapper mount(MyComponent /); // 所有包含 btn 类的节点中剔除同时包含 btn--disabled 类的节点 const enabledButtons wrapper.find(.btn).not(.btn--disabled); expect(enabledButtons).to.have.lengthOf(2);由于not返回新的 wrapper可以继续链式调用.hostNodes()、.at(index)、.first()等方法进行二次筛选与取值const wrapper mount(MyComponent /); const firstEnabled wrapper.find(.item).not(.item--hidden).first();not与相关方法的对比文档末尾列出了两个密切相关的兄弟方法.filterWhere(predicate) ReactWrapper接受谓词函数而非选择器对每个节点调用predicate(wrapper)保留返回true的节点。not恰好可以看成filterWhere的反选形态.not(sel)等价于filterWhere((n) !n.is(sel))。.filter(selector) ReactWrapper接受同样的EnzymeSelector但保留的是匹配选择器的节点是not的直接逆操作。三者对比速查方法参数保留规则底层复用.filter(selector)EnzymeSelector匹配选择器buildPredicatefilterWhereUnwrapped.not(selector)EnzymeSelector不匹配选择器buildPredicate取反 filterWhereUnwrapped.filterWhere(predicate)函数谓词返回truefilterWhereUnwrapped从 ReactWrapper.js 的源码可以看到三者是相邻实现的filter与not共享buildPredicate区别仅在谓词是否取反——这也是为什么文档称not是filter的 negation or inverse。另外需要注意not是对当前 wrapper 已有节点的筛选不深入渲染树查找后代若需要查找并排除应先用.find(selector)定位节点集再在其结果上调用.not()。常见问题与注意事项不支持复杂 CSS 选择器not底层走buildPredicate对包含后代/子代组合符的选择器如.parent .child会直接抛出TypeError。需要按谓词逻辑筛选时请改用.filterWhere(predicate)。props 对象不能含undefined值{ disabled: undefined }会触发类型错误请改用filterWhere。空结果也是合法结果所有节点都匹配选择器时如示例中find(.foo).not(div)返回的 wrapper 长度为 0用于断言全部符合或不存在例外非常顺手。不影响原 wrappernot返回新 wrapper原 wrapper 的节点集合与length保持不变可放心继续使用。两种渲染模式行为一致由于两个 wrapper 类共用同一套filterWhereUnwrapped与buildPredicatemount与shallow下.not的语义完全对齐docs/api/ShallowWrapper/not.md 提供了同构的文档说明共享测试 not.jsx 也同时覆盖两种 wrapper。小结.not(selector)是 enzyme 节点筛选中排除法的核心工具它复用filter的选择器解析与过滤管线仅对谓词取反从而在 ReactWrapper 与 ShallowWrapper 上提供一致、可链式调用、不修改原 wrapper 的反向筛选能力。掌握它与.filter、.filterWhere的差异就能用最少的代码写出排除特定节点的精确断言。赞分享测试前端【免费下载链接】enzymeJavaScript Testing utilities for React项目地址https://gitcode.com/gh_mirrors/en/enzyme点击查看免费下载相关推荐Enzyme 的 .some(selector) 方法如何判断包装器中是否存在匹配节点Enzyme 的 .some selector 方法如何判断包装器中是否存在匹配节点 .some selector 是 enzyme 为 ReactWrapp测试前端Enzyme 选择器匹配判定全面解析 .is(selector) 方法ReactWrapper / ShallowWrapperEnzyme 选择器匹配判定全面解析 .is selector 方法ReactWrapper / ShallowWrapper 本文围绕 enzyme 核测试前端Enzyme ReactWrapper.exists() 方法完全指南检测节点存在性与选择器匹配Enzyme ReactWrapper.exists 方法完全指南检测节点存在性与选择器匹配 .exists 是 Enzyme 测试工具库中用于判断 Wrap测试前端上一篇Grug-12B性能优化技巧10个方法提升推理速度与准确性下一篇Claudable数据库集成Supabase连接配置与实时数据处理完整指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考