首页 > 解决方案 > 反应测试:“TypeError:MutationObserver 不是构造函数”

问题描述

问题

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

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

TypeError: MutationObserver is not a constructor

    at /<path_to_repo>/node_modules/@testing-library/dom/dist/wait-for.js:78:18

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

相关包版本(在消费代码库中):

运行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。更改我的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-fourteenand jest-environment-jsdom-fifteen,并在强迫jsdomto 的同时尝试^14.0.0。结果相同。

使用mutationobserver-shim

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

ReferenceError: window is not defined
  at Object.<anonymous> (/<path_to_repo>/node_modules/mutationobserver-shim/dist/mutationobserver.min.js:12:1)

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

一个不太好的解决方案

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

我的问题

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

标签: node.jsreactjsjestjsmutation-observers

解决方案


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

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

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


推荐阅读