React Speed Coding 测试完全指南:Enzyme + Mocha + Chai 编写 React 组件 BDD 测试的 8 个技巧
2026/9/19 7:35:47 网站建设 项目流程

React Speed Coding 测试完全指南:Enzyme + Mocha + Chai 编写 React 组件 BDD 测试的 8 个技巧

【免费下载链接】reactspeedcoding:rocket: Learn React with 30 reusable components, 15 chapters, and 3 single page apps. Fast start project with JavaScript ES6. React Hot Loading. React Router. Redux. PostCSS, FlexBox styling. Firebase database. Webpack packaging. Enzyme, Mocha, Chai BDD testing. ESLint and StyleLint. Browsersync.项目地址: https://gitcode.com/gh_mirrors/re/reactspeedcoding

React Speed Coding 是一个包含 30 个可复用组件、15 个章节和 3 个单页应用的 React 学习项目,其测试体系基于Enzyme + Mocha + Chai这套经典的 React 组件 BDD 测试组合。本文将结合项目中的真实测试代码,拆解 8 个核心技巧,带你从"不会写测试"到能独立完成 React 组件行为测试。

💡 动手前建议先获取代码:git clone https://gitcode.com/gh_mirrors/re/reactspeedcoding

测试工具栈一览:测试、Lint 与自动刷新如何协作

上图展示了项目质量保障的完整链路:Mocha 测试 + ESLint / StyleLint 代码检查 + Browsersync 浏览器自动刷新,三者共同保证代码又快又稳。

工具角色在项目中
MochaBDD 测试运行器test/**.spec.js用例执行
Chai(expect 风格)断言库expect(...).to.equal(...)
EnzymeReact 组件测试工具shallow/render/mount三层渲染
jsdom模拟浏览器环境browser.js
sinon行为验证(spy/stub)01_workflow.spec.js
babel-istanbul测试覆盖率npm run cover

技巧 1:一条命令跑完测试与静态检查

项目的 package.json 把测试流程编排成了几条 npm 脚本,这是新手最容易忽略但最实用的技巧——先约定命令,再谈测试本身

npm test # ESLint + StyleLint + Mocha 三步走 npm run test:mocha # 只跑 Mocha 组件测试 npm run cover # 生成测试覆盖率报告

其中 test:mocha 的关键点在于把 test/helpers/browser.js 作为第一个参数传给 Mocha——它会在任何测试用例执行前先搭建好模拟浏览器环境(见技巧 2)。

技巧 2:用 jsdom 为 React 测试搭建浏览器环境

React 组件依赖documentwindownavigator这些浏览器对象,而 Mocha 跑在 Node 里,所以测试前必须先"伪造"一个浏览器。项目的做法非常干净:

global.document = jsdom(''); global.window = document.defaultView; global.navigator = { userAgent: 'node.js' };

完整实现见 browser.js。记住这个模式:Node 环境 + jsdom 注入全局对象 = React 测试可用的 DOM

技巧 3:用 Mocha 的 describe/it 组织 BDD 测试

BDD(行为驱动开发)的核心是让测试读起来像需求描述。项目约定用<组件名 />作为describe标题,用should ...描述预期行为,例如 02_mocha_chai.spec.js 就演示了三层嵌套结构:

describe('Mocha Chai Demo', () => { describe('Array operations', () => { describe('#indexOf()', () => { it('should return -1 when the value is not present', () => { expect([1, 2, 3].indexOf(5)).to.equal(-1); }); }); }); });

另外,项目还特意放了一个 Mocha 超时示例,教你用this.timeout(500)调整超时时间——异步测试经常因此误报失败,提前知道这个开关能省不少排查时间。

技巧 4:Chai expect 断言要"说人话"

Chai 的 expect 风格支持链式调用,项目里高频出现的断言模式有四种:

断言写法含义项目示例
to.equal(值)精确相等01_workflow.spec.js 校验stepsIndex为 1
to.have.length(n)数量校验02_card.spec.js 校验.card只有 1 个
to.be.defined属性存在01_workflow.spec.js 校验stepsprop 已定义
to.be.above(n)数量下限03_roadmap.spec.js 校验组件数量大于 2

小技巧:用数量断言代替全量快照,列表类组件(如 Roadmap)数据经常变化,length.above(2)比逐条比对更抗变化。

技巧 5:Enzyme 三层渲染,按需选择测试深度

这是整篇文章最值钱的技巧。Enzyme 提供三种渲染方式,测试强度逐级递增:

上图就是项目中的 Roadmap 应用(React 组件测试的实战对象),它的 测试文件 同时用到了三种渲染方式:

  • shallow(浅渲染):只渲染被测组件一层,最快,适合单元测试。如 02_card.spec.js 用wrapper.is('.card')校验根节点类名;
  • render(静态 HTML):输出真实 DOM,适合校验整棵子树的最终结构。如 03_roadmap.spec.js 校验.search-filter存在;
  • mount(完整挂载):带状态、带事件的全量渲染,适合测试交互行为(见技巧 6、7)。

经验法则:先 shallow,不够再 mount,能跑快的测试跑得越快,整个套件就越稳。

技巧 6:simulate 模拟用户点击,测试交互状态

静态渲染只能证明"组件画出来了",真正的行为测试要模拟用户操作。Workflow 组件测试 展示了标准套路——渲染 → 触发事件 → 断言状态变化

const wrapper = mount(<Workflow />); wrapper.find('button.default').simulate('click'); expect(wrapper.state('stepsIndex')).to.equal(1);

被测试的 Workflow 组件 点击按钮后应把stepsIndex从 0 递增到 1,测试精确验证了这一点。还有一招wrapper.setState({ stepsIndex: 1 })可以先手动设置初始状态再触发,用于测试"第 N 次点击"这类依赖前置状态的场景。

技巧 7:用 sinon.spy 验证"方法被调用了"

有时你不关心方法内部逻辑(那些逻辑另有单元测试),只关心它是否被触发。项目用 sinon 做了教科书式的演示,见 01_workflow.spec.js:

sinon.spy(Workflow.prototype, 'cycleScenario'); const wrapper = mount(<Workflow />); expect(Workflow.prototype.cycleScenario.calledOnce).to.equal(false); // 点击前:没调用 wrapper.find('button.primary').simulate('click'); expect(Workflow.prototype.cycleScenario.calledOnce).to.equal(true); // 点击后:调用了

"调用前断言一次、调用后再断言一次"——这种前后对照写法能彻底排除假阳性,是行为验证的推荐姿势。

技巧 8:测试 Redux Store,用空测试当 TODO 清单

Roadmap 是项目里最复杂的 Redux 单页应用,测试分两部分:

① 组件测试需要 Provider 包裹。React Redux 组件必须拿到 store 才能渲染,项目用 roadmapHydrate 预填充数据后,再用<Provider store={store}>包住组件(见 03_roadmap.spec.js)。

② 独立测试状态树。不渲染任何组件,直接dispatchaction 验证 state 变化,如 setCategoryFilter 与 setSearchText 测试。

③ 留白即 TODO。Mocha 允许只写it('...')不写函数体,测试会以"待办"状态列出。项目大量使用这一招,例如 03_roadmap.spec.js:

it('should execute onChange() when user presses key in search box'); it('should update state tree after onChange() is called in search field');

这让测试文件同时成为验收清单,新接手的人一眼就知道还欠哪些测试。

8 个技巧速查清单

#技巧关键命令/写法参考文件
1一键跑测试+Lintnpm testpackage.json
2jsdom 模拟浏览器global.document = jsdom('')browser.js
3BDD 结构组织describe/it/this.timeout02_mocha_chai.spec.js
4expect 断言模式equal/length/defined/above01_workflow.spec.js
5Enzyme 三层渲染shallowrendermount03_roadmap.spec.js
6模拟交互simulate('click')+state()断言01_workflow.spec.js
7行为验证sinon.spy+calledOnce前后对照01_workflow.spec.js
8Redux 测试与 TODO<Provider>包裹 + 空it占位03_roadmap.spec.js

🎯 总结:React 组件测试的黄金路径就是jsdom 铺路 → shallow 快测 → mount 测交互 → sinon 验行为 → 空 it 记 TODO。照着这 8 个技巧,你就能为任何 React 组件写出既快又可维护的 BDD 测试。

【免费下载链接】reactspeedcoding:rocket: Learn React with 30 reusable components, 15 chapters, and 3 single page apps. Fast start project with JavaScript ES6. React Hot Loading. React Router. Redux. PostCSS, FlexBox styling. Firebase database. Webpack packaging. Enzyme, Mocha, Chai BDD testing. ESLint and StyleLint. Browsersync.项目地址: https://gitcode.com/gh_mirrors/re/reactspeedcoding

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询