- 测试
- 前端
【免费下载链接】enzyme
JavaScript Testing utilities for React
导读
.first()是 EnzymeShallowWrapper提供的高频便捷方法,用于将当前包装器所匹配的节点集合缩减为集合中的第一个节点,其行为等价于.at(0)。在浅渲染测试中,当你通过find得到一组匹配节点、却只需要断言或操作其中第一个时,.first()是最简洁的写法。读完本文,你将掌握.first()的返回语义、与.at(0)/.last()/.get(0)的等价关系、底层实现原理,以及配套的共享测试用例,从而在 enzyme 项目中写出更精炼、可读性更高的断言。
.first()方法签名与返回值
根据 docs/api/ShallowWrapper/first.md 的官方定义:
- 签名:
.first() => ShallowWrapper - 语义:将匹配节点集合缩减为集合中的第一个节点,等价于
.at(0) - 返回值:返回一个新的
ShallowWrapper,它包装了当前节点集合中的第一个节点
与.at(index)需要显式传入下标不同,.first()无需任何参数,直接作用于当前包装器内部持有的节点数组,适合在链式调用中直观表达"取第一个"的意图。
基本用法示例
原文档给出的示例非常简洁,适用于shallow渲染:
const wrapper = shallow(<MyComponent />); expect(wrapper.find(Foo).first().props().foo).to.equal('bar');这里的关键点在于:wrapper.find(Foo)可能匹配到多个<Foo />节点,而.first()将结果缩减为第一个匹配的Foo,随后即可安全地调用.props()读取其 props 并断言。在 docs/api/ShallowWrapper/first.md 中,这一示例的核心链条为find → first → props。
同样的方法在ReactWrapper(mount渲染)上也存在,见 docs/api/ReactWrapper/first.md:
const wrapper = mount(<MyComponent />); expect(wrapper.find(Foo).first().props().foo).to.equal('bar');可见.first()在ShallowWrapper与ReactWrapper两个包装器上行为一致,仅返回的包装器类型不同(ShallowWrapper/ReactWrapper)。
结合类选择器的多节点缩减
当同一选择器匹配多个节点时,.first()的"缩减"语义体现得最明显。仓库的共享测试 packages/enzyme-test-suite/test/shared/methods/first.jsx 给出了一个完整可运行的用例:
import React from 'react'; import { expect } from 'chai'; export default function describeFirst({ Wrap }) { describe('.first()', () => { it('returns the first node in the current set', () => { const wrapper = Wrap(( <div> <div className="bar baz" /> <div className="bar" /> <div className="bar" /> <div className="bar" /> </div> )); expect(wrapper.find('.bar').first().hasClass('baz')).to.equal(true); }); }); }该测试通过Wrap抽象同时适配shallow与mount(Wrap在 packages/enzyme-test-suite/test/_helpers/index.jsx 中按渲染方式注入)。渲染结构中有 4 个.bar节点,其中第一个同时带有baz类名。wrapper.find('.bar').first()返回包装第一个.bar节点的新包装器,因此.hasClass('baz')为true。这个用例从行为层面验证了"缩减到第一个"的定义:即使后续三个节点都不含baz,.first()也能准确命中集合首项。
底层实现:.first()即.at(0)
在源码层面,.first()的实现非常直观,见 packages/enzyme/src/ShallowWrapper.js#L1599-L1606:
/** * Returns a wrapper around the first node of the current wrapper. * * @returns {ShallowWrapper} */ first() { return this.at(0); }其内部直接委托给.at(0)。而.at(index)的实现见 packages/enzyme/src/ShallowWrapper.js#L1585-L1597:
at(index) { const nodes = this.getNodesInternal(); if (index < nodes.length) { return this.wrap(nodes[index]); } return this.wrap([]); }完整的调用链可以概括为:
getNodesInternal()取出当前包装器内部维护的节点数组;- 判断
index(此处为 0)是否小于节点数组长度; - 若存在,调用
wrap(nodes[index])返回一个只包含该节点的新包装器; - 若集合为空(
index >= nodes.length),则返回包装空数组的ShallowWrapper。
其中wrap的实现在 packages/enzyme/src/ShallowWrapper.js#L1663-L1668:若传入节点已是ShallowWrapper实例则原样返回,否则以当前包装器的ROOT为根新建ShallowWrapper。这意味着.first()返回的新包装器共享原包装器的根节点,后续的.props()、.hasClass()、.simulate()等操作都作用于这唯一的首节点。
ReactWrapper侧的实现完全一致,见 packages/enzyme/src/ReactWrapper.js#L1119-L1126,其first()同样返回this.at(0)。
边界情况与链式调用建议
空集合:当
.find()未匹配到任何节点时,nodes.length === 0,at(0)返回包装空数组的新包装器(this.wrap([]))。此时.first()返回的包装器length === 0,后续若直接调用.props()可能取到undefined。因此建议结合.exists()先判断是否存在匹配节点:const firstBar = wrapper.find('.bar').first(); if (firstBar.exists()) { // 安全读取 props }与
.at(index)的等价关系:原文档明确指出.first()"just like.at(0)",二者在结果上完全等价,只是.first()在语义上更自解释。相关方法矩阵参见 docs/api/ShallowWrapper/at.md 与 docs/api/ShallowWrapper/last.md:方法 等价调用 返回内容 .first().at(0)包装集合首节点的新 ShallowWrapper.last().at(length - 1)包装集合末节点的新 ShallowWrapper.at(index).first()/.last()的通用形式包装指定下标节点的新 ShallowWrapper.get(index)与 .at(index)相似直接返回 React 节点本身,而非包装器 链式调用建议:
.first()常与find、findWhere等返回多节点的 API 配合,也可作为everyWhere、someWhere之外获取单节点的高频入口。由于它返回的是新包装器而非原包装器,链式操作不会污染原始结果,天然支持"取首个 → 断言 → 取下一个"的流程。
小结
.first()是 EnzymeShallowWrapper中"按位置缩减节点集合"最常用的便捷方法:无需参数即可取集合首节点,源码上直接委托.at(0)(ShallowWrapper.js),并通过wrap生成与当前包装器共享根节点的全新包装器。无论是配合find(Foo).first().props()读取首个匹配组件的属性,还是结合findWhere缩小查询范围后取首项断言,它都能显著提升测试链的可读性。结合本文引用的共享测试用例 first.jsx,你可以在自己的浅渲染测试中放心使用这一模式。
- 测试
- 前端
【免费下载链接】enzyme
JavaScript Testing utilities for React
相关推荐
Enzyme ReactWrapper `.last()` 方法详解:取匹配节点集合的最后一个元素
Enzyme ReactWrapper .last 方法详解:取匹配节点集合的最后一个元素 .last 是 Enzyme 测试工具中用于将当前 wrapper
测试前端Enzyme ReactWrapper.first() 方法详解:快速定位渲染树中的第一个匹配节点
Enzyme ReactWrapper.first 方法详解:快速定位渲染树中的第一个匹配节点 .first 是 Enzyme 中用于将当前匹配节点集合缩减为集
测试前端Enzyme ReactWrapper.reduce 方法完全指南:将节点集合归约为单一值
Enzyme ReactWrapper.reduce 方法完全指南:将节点集合归约为单一值 导读 reduce 是 Enzyme ReactWrapper 提供
测试前端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考