enzyme ReactWrapper 的 `.length` 属性:统计包裹的 React 节点数量
enzyme ReactWrapper 的.length属性统计包裹的 React 节点数量【免费下载链接】enzymeJavaScript Testing utilities for React项目地址: https://gitcode.com/gh_mirrors/en/enzyme.length是 enzyme 中ReactWrapper以及ShallowWrapper提供的一个只读属性用于返回当前 wrapper 所包裹的 React 节点数量。在断言查询结果、判断元素是否存在、控制循环遍历范围等场景中它是测试代码里最常用的基础能力之一。读完本文你将掌握.length的语义、源码实现原理以及它在 enzyme 测试套件中的典型用法。属性签名.length numberlength是 wrapper 对象上的一个**属性property**而非方法因此直接读取即可不需要调用括号。返回值返回类型为Number即当前 wrapper 内部节点列表node list中节点的总数。场景返回值空 wrapper未匹配到任何节点0包裹单个节点最常见的根 wrapper 情况1通过find/children等匹配到多个节点匹配到的节点数量基本示例根据 docs/api/ReactWrapper/length.md 中的官方示例const wrapper mount(div /); expect(wrapper.length).to.equal(1);mount(div /)只渲染了一个根节点因此wrapper.length为1。类似地docs/api/ShallowWrapper/length.md 对shallow渲染也定义了完全相同的语义const wrapper shallow(div /); expect(wrapper.length).to.equal(1);源码实现length 从何而来length的值在 wrapper 创建或更新内部节点列表时被同步设置核心逻辑位于两个 wrapper 的实现文件中。以ReactWrapper为例packages/enzyme/src/ReactWrapper.js#L84-L96 中的privateSetNodes函数负责统一管理内部节点数组并在最后写入lengthfunction privateSetNodes(wrapper, nodes) { if (!nodes) { privateSet(wrapper, NODE, null); privateSet(wrapper, NODES, []); } else if (!Array.isArray(nodes)) { privateSet(wrapper, NODE, nodes); privateSet(wrapper, NODES, [nodes]); } else { privateSet(wrapper, NODE, nodes[0]); privateSet(wrapper, NODES, nodes); } privateSet(wrapper, length, wrapper[NODES].length); }可以看到当传入的nodes为数组时NODES保存整个数组NODE指向第一个节点当传入单个节点时会被包装成[nodes]单元素数组无论哪种情况length始终等于内部节点数组NODES的长度即length本质上是节点数组大小的镜像。ShallowWrapper在 packages/enzyme/src/ShallowWrapper.js#L180-L189 中实现了同样的逻辑因此两种渲染模式下.length的行为保持一致。由于find、filter、children、parents等查询方法都会通过wrap()生成一个包裹了新的节点子集的新 wrapper内部同样走privateSetNodes所以这些查询结果的.length能准确反映匹配数量。核心应用场景1. 断言查询匹配数量这是.length最典型的用途——验证find等选择器命中了预期的节点数。在 enzyme 官方测试套件中可以找到大量印证例如 packages/enzyme-test-suite/test/shared/methods/find.jsxexpect(wrapper.find(input)).to.have.lengthOf(2); expect(wrapper.find(button)).to.have.lengthOf(1); expect(wrapper.find(Foo)).to.have.lengthOf(2);packages/enzyme-test-suite/test/shared/methods/children.jsx 中也大量使用lengthOf校验children()的结果数量expect(wrapper).to.have.lengthOf(3); expect(wrapper.children()).to.have.lengthOf(1); expect(wrapper.children()).to.have.lengthOf(0);在 Chai 断言库中既可以直接比较expect(wrapper.find(.foo).length).to.equal(3);也可以使用更语义化的lengthOf或length属性链expect(wrapper.find(.foo)).to.have.lengthOf(3);2. 判断元素是否存在exists()方法的底层实现就基于length。在 packages/enzyme/src/ReactWrapper.js#L1156 中return arguments.length 0 ? this.find(selector).exists() : this.length 0;即无参调用时exists()等价于判断length 0。官方测试 packages/enzyme-test-suite/test/shared/methods/exists.jsx 也验证了这一点expect(wrapper.find(.bar).exists()).to.equal(false); expect(wrapper.find(.foo).exists()).to.equal(true);因此以下两种写法在语义上等价// 写法一直接读 length if (wrapper.find(.foo).length 0) { ... } // 写法二exists() if (wrapper.find(.foo).exists()) { ... }3. 约束单节点操作不少依赖单一节点语义的 API 会检查length ! 1并抛出异常。例如 packages/enzyme/src/ReactWrapper.js#L1170-L1171 的single工具if (this.length ! 1) { throw new Error(Method “${fnName}” is meant to be run on 1 node. ${this.length} found instead.); }这意味着当你对find(.foo)可能匹配 0 个或多个节点的结果直接调用prop()、text()、getNode()见 packages/enzyme/src/ReactWrapper.js#L162-L165等单节点方法时enzyme 会利用length提前给出明确报错。这也提醒我们在调用这类方法前可以先断言.length 1。4. 驱动遍历与聚合map、forEach、reduce、some、every、at、slice等方法的遍历范围都以内部节点数组即length对应的数组为准例如at(index)实现中的越界保护packages/enzyme/src/ReactWrapper.js#L1113与last()直接使用this.length - 1packages/enzyme/src/ReactWrapper.js#L1134return this.at(this.length - 1);mount 与 shallow 下 length 的差异两种渲染模式下.length的语义一致都是wrapper 包裹的节点数但根 wrapper 的典型取值可能不同mount(Component /)真实挂载后根 wrapper 包裹渲染出的根节点通常为1shallow(Component /)浅渲染只渲染一层根 wrapper 包裹组件本身对应的元素通常也是1。而无论哪种模式一旦通过find、children、filter等产生多节点 wrapperlength即为实际匹配数。空匹配如wrapper.find(.not-exist)的length为0。相关 API 与进一步阅读docs/api/ReactWrapper/find.md选择器查询结果 wrapper 的length反映匹配数docs/api/ReactWrapper/children.md、docs/api/ReactWrapper/parents.md遍历子节点/祖先同样可用length断言数量docs/api/ReactWrapper/exists.md基于length 0的快捷判断docs/api/ReactWrapper/isEmpty.md空 wrapper 判断docs/api/ReactWrapper/at.md、docs/api/ReactWrapper/last.md依赖length的索引访问docs/api/ShallowWrapper/length.md浅渲染模式下语义相同的属性说明小结.length是 enzyme wrapper 最基础也最常用的只读属性它直接镜像内部节点数组的长度源码层面由privateSetNodes在节点更新时同步维护packages/enzyme/src/ReactWrapper.js#L84-L96。在编写测试时用expect(wrapper.find(selector)).to.have.lengthOf(n)断言查询结果、用length 0判断存在性是既简洁又可靠的最佳实践。【免费下载链接】enzymeJavaScript Testing utilities for React项目地址: https://gitcode.com/gh_mirrors/en/enzyme创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考