React 测试:“TypeError:MutationObserver 不是构造函数”

mig*_*aus 5 node.js mutation-observers reactjs jestjs

问题

\n

我正在尝试测试内部组件库的新版本,该库最近升级了一些依赖项,现在在内部使用Jest 26。该库还导出一些测试助手。

\n

在使用上述组件库的另一个代码库中,我在运行某些单元测试时得到以下信息:

\n
TypeError: MutationObserver is not a constructor\n\n    at /<path_to_repo>/node_modules/@testing-library/dom/dist/wait-for.js:78:18\n
Run Code Online (Sandbox Code Playgroud)\n

这可能与组件库导出的测试助手依赖于 Jest 26 这一事实有关,也可能无关。(很难判断这些助手是否正在被使用——我们有一些非常大的“单元”) “测试。)

\n

相关软件包版本(在使用代码库中):

\n
    \n
  • 反应脚本 3.4.4
  • \n
  • 开玩笑 24.9.0
  • \n
  • 测试库/dom 7.26.3
  • \n
  • 测试库/jest-dom 5.10.0
  • \n
  • 测试库/反应 ^10.0.0
  • \n
\n

运行yarn list jsdom结果如下:

\n
\xe2\x94\x9c\xe2\x94\x80 jest-environment-jsdom-fourteen@1.0.1\n\xe2\x94\x82  \xe2\x94\x94\xe2\x94\x80 jsdom@14.1.0\n\xe2\x94\x9c\xe2\x94\x80 jest-environment-jsdom@24.9.0\n\xe2\x94\x82  \xe2\x94\x94\xe2\x94\x80 jsdom@11.12.0\n\xe2\x94\x94\xe2\x94\x80 jsdom@16.4.0\n
Run Code Online (Sandbox Code Playgroud)\n

我知道升级react-scripts和 Jest 可能会解决这个问题,但我正在尝试找到一种不涉及此问题的方法。(理想情况下,我们不希望这是升级到新组件库版本的先决条件。)

\n

尝试的解决方案

\n

强制更新jsdom

\n

首先我尝试添加

\n
"resolutions": {\n  "jsdom": "^14.0.0"\n},\n
Run Code Online (Sandbox Code Playgroud)\n

给我的package.json。这确实只产生yarn list jsdom输出jsdom@14.1.0,但我仍然得到相同的结果TypeError。解决^15.0.0导致相同的错误,并解决给^16.0.0我以下错误:

\n
TypeError: this.dom.runVMScript is not a function\n\n  at JSDOMEnvironment.runScript (node_modules/jest-environment-jsdom/build/index.js:187:23)\n
Run Code Online (Sandbox Code Playgroud)\n

使用jest-environment-jsdom-*

\n

我尝试通过安装来遵循此线程jest-environment-jsom-sixteen。更改我的test脚本package.json并运行yarn test --showConfig会产生大量信息,包括以下行:

\n
"testEnvironment": "/<path_to_repo>/node_modules/jest-environment-jsdom-sixteen/lib/index.js",\n
Run Code Online (Sandbox Code Playgroud)\n

如果我console.log(navigator.userAgent)在测试中添加一个,我也会得到

\n
Mozilla/5.0 (darwin) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/16.4.0\n
Run Code Online (Sandbox Code Playgroud)\n

但是,我仍然得到同样的结果TypeError: MutationObserver is not a constructor

\n

我也尝试jest-environment-jsdom-fourteenjest-environment-jsdom-fifteen,尝试过,也强迫jsdom^14.0.0。相同的结果。

\n

使用mutationobserver-shim

\n

我运行并在我的(这是我的 Jest 配置中指向的)中yarn add -D mutationobserver-shim导入它(使用),但这导致了以下错误:import \'mutationobserver-shim\'jestSetup.tsglobalSetup

\n
ReferenceError: window is not defined\n  at Object.<anonymous> (/<path_to_repo>/node_modules/mutationobserver-shim/dist/mutationobserver.min.js:12:1)\n
Run Code Online (Sandbox Code Playgroud)\n

将导入添加到我的测试文件中产生TypeError与上面相同的结果,并将 a 添加console.log(global.MutationObserver)到我的测试文件中产生undefined.

\n

一个不太好的解决方案

\n

经过大量的试验和错误,我发现如果我 1) 已经jest-environment-jsdom-sixteen安装并告诉 Jest 使用它,2) 添加import \'mutationobserver-shim\' 到我的测试文件中,测试就会通过。但是,如果我将导入添加到我的 JestglobalSetup文件中,它就不起作用。我得到ReferenceError: window is not defined和以前一样的错误。

\n

我的问题

\n

如何在不要求组件库的用户向其所有测试文件添加导入语句的情况下消除这两个错误?

\n

Est*_*ask 5

应该在 中应用 polyfill setupFilesAfterEnv,因为这是jsdom环境实例化并window变得可用的地方。window不应该在中使用,globalSetup因为它不在测试范围内运行。

如果这是一个未弹出的 create-react-app 项目,则对应的安装文件setupFilesAfterEnvsrc/setupTests.ts( src/setupTests.js)。

jsdom版本导致错误意味着它与旧 Jest 版本 (24) 不兼容。它们应该被弹出并升级,或者react-scripts@4必须使用支持 Jest 26 的较新的 CRA ( )。