问题描述
问题
我正在尝试测试内部组件库的新版本,该组件库最近升级了一些依赖项,现在在内部使用Jest 26。该库还导出了一些测试助手。
在另一个利用上述组件库的代码库中,当运行某些单元测试时,我得到以下信息:
TypeError: MutationObserver is not a constructor
at /<path_to_repo>/node_modules/@testing-library/dom/dist/wait-for.js:78:18
这可能与或可能与以下事实无关:组件库导出的测试帮助程序依赖于Jest26。(很难确定这些帮助程序是否正在使用-我们有一些非常大的“单元”测试。)
相关的软件包版本(在使用的代码库中):
- 反应脚本3.4.4
- 笑话24.9.0
- testing-library / dom 7.26.3
- testing-library / jest-dom 5.10.0
- testing-library / react ^ 10.0.0
运行yarn list jsdom
会产生以下结果:
├─ jest-environment-jsdom-fourteen@1.0.1
│ └─ jsdom@14.1.0
├─ jest-environment-jsdom@24.9.0
│ └─ jsdom@11.12.0
└─ jsdom@16.4.0
我知道升级react-scripts
和Jest可能会解决此问题,但是我试图找到一种不涉及此问题的方法。 (理想情况下,我们不希望这成为升级到新的组件库版本的先决条件。)
尝试的解决方案
强制更新jsdom
首先我尝试添加
"resolutions": {
"jsdom": "^14.0.0"
},
到我的package.json
。这确实使yarn list jsdom
仅输出jsdom@14.1.0
,但是我仍然得到相同的TypeError
。解析为^15.0.0
会导致相同的错误,而解析为^16.0.0
给了我以下错误:
TypeError: this.dom.runVMScript is not a function
at JSDOMEnvironment.runScript (node_modules/jest-environment-jsdom/build/index.js:187:23)
使用jest-environment-jsdom-*
我尝试通过安装jest-environment-jsom-sixteen
来关注this thread。在test
中更改我的package.json
脚本并运行yarn test --showConfig
会产生一堆信息,包括以下行:
"testEnvironment": "/<path_to_repo>/node_modules/jest-environment-jsdom-sixteen/lib/index.js",
如果我在测试中添加console.log(navigator.userAgent)
,我也会得到
Mozilla/5.0 (darwin) AppleWebKit/537.36 (KHTML,like Gecko) jsdom/16.4.0
但是,我仍然得到相同的TypeError: MutationObserver is not a constructor
。
我还尝试了jest-environment-jsdom-fourteen
和jest-environment-jsdom-fifteen
,并在将jsdom
强制为^14.0.0
的同时尝试了。结果相同。
使用mutationobserver-shim
我运行了yarn add -D mutationobserver-shim
并将其(与import 'mutationobserver-shim'
一起导入了jestSetup.ts
(这是我的Jest配置中的globalSetup
所指向的),但这导致了出现以下错误:
ReferenceError: window is not defined
at Object.<anonymous> (/<path_to_repo>/node_modules/mutationobserver-shim/dist/mutationobserver.min.js:12:1)
相反,将导入添加到我的测试文件中会产生与上述相同的TypeError
,向我的测试文件中添加console.log(global.MutationObserver)
会得到undefined
。
一个不太好的解决方案
经过反复试验,我发现如果我1)安装了jest-environment-jsdom-sixteen
并告诉Jest使用它,2)在测试文件中添加import 'mutationobserver-shim'
,并且测试将通过。但是,如果我将导入添加到我的Jest globalSetup
文件中,它将无法正常工作。我收到与以前相同的ReferenceError: window is not defined
错误。
我的问题
在不要求组件库用户向所有测试文件中添加导入语句的情况下,如何消除这两个错误?
解决方法
应该在setupFilesAfterEnv
中应用polyfill,因为这是实例化JSDOM环境并且window
可用的地方。 window
在globalSetup
中不可用,因为它不在测试范围内运行。
如果这是一个未创建的create-react-app项目,则与setupFilesAfterEnv
对应的安装文件为src/setupTests.ts
(src/setupTests.js
)。
较新的jsdom
版本导致错误,表示它与旧的Jest(jest@24
)不兼容。应该弹出并升级它们,否则必须使用具有Jest 26支持的更新的CRA(react-scripts@4
)。