编写JavaScript测试代码时为何React依赖要在beforeEach中引入?
为什么react-dom测试要在beforeEach中引入依赖
这种写法是 Jest 测试的常用最佳实践,核心是配合jest.resetModules()实现测试用例的完全隔离,具体原因有以下几点:
- 避免测试用例之间的相互污染
Node 以及 Jest 的模块系统默认是单例模式,常规的文件头部引入写法会让整个测试文件的所有用例共用同一份模块实例。如果某个测试用例修改了模块导出的对象、或者修改了模块内部的状态,就会影响后续所有测试的运行结果。
而jest.resetModules()会清空 Jest 的模块缓存,每次beforeEach重新引入依赖,相当于每个测试用例都能拿到全新的、未被修改过的模块实例,从根源上避免了用例之间的交叉影响。 - 支持动态调整模块实现
React 源码的测试场景经常需要切换不同的模块版本:比如切换开发/生产环境的 React 构建产物、开启/关闭某个特性开关、替换某个依赖的 Mock 实现。如果是文件头部提前引入依赖,就无法在单个测试用例中动态调整模块的加载结果。
放到beforeEach中引入的话,你可以在单个测试用例里先完成自定义的模块 Mock、环境变量配置,再执行引入逻辑,就能拿到符合当前测试要求的模块实例。示例如下:it('测试生产环境下的行为', () => { // 先修改环境变量 process.env.NODE_ENV = 'production' // 手动清空模块缓存 jest.resetModules() // 引入的就是生产环境版本的React React = require('react') // 后续测试逻辑 }) - 规避模块初始化的时机问题
很多模块在被引入时会执行顶层的初始化代码,这些代码可能依赖测试运行时的环境配置(比如 Jest 的全局 Mock、jsdom 的 DOM 环境配置)。如果是文件头部引入,初始化代码会在测试文件加载阶段就执行,此时测试环境的配置可能还没有准备完成,容易出现意料之外的报错。
放到beforeEach中引入,会在每个测试用例的环境准备完成之后才执行模块初始化,时机更可控。
内容的提问来源于stack exchange,提问作者Jacob
相关产品推荐
相关产品推荐

