Node.js 反应测试:“;TypeError:MutationObserver不是构造函数; 问题
我正在尝试测试一个新版本的内部组件库,它最近升级了一些依赖项,现在在内部使用Jest 26。该库还导出一些测试助手 在另一个利用上述组件库的代码库中,当运行某些单元测试时,我得到以下信息:Node.js 反应测试:“;TypeError:MutationObserver不是构造函数; 问题,node.js,reactjs,jestjs,mutation-observers,Node.js,Reactjs,Jestjs,Mutation Observers,我正在尝试测试一个新版本的内部组件库,它最近升级了一些依赖项,现在在内部使用Jest 26。该库还导出一些测试助手 在另一个利用上述组件库的代码库中,当运行某些单元测试时,我得到以下信息: TypeError: MutationObserver is not a constructor at /<path_to_repo>/node_modules/@testing-library/dom/dist/wait-for.js:78:18 我知道升级react scripts
TypeError: MutationObserver is not a constructor
at /<path_to_repo>/node_modules/@testing-library/dom/dist/wait-for.js:78:18
我知道升级react scripts
和Jest可能会解决这个问题,但我正在尝试找到一种不涉及这个问题的方法。(理想情况下,我们不希望这成为升级到新组件库版本的先决条件。)
尝试的解决方案
强制更新的jsdom
首先,我尝试添加
“决议”:{
“jsdom”:“^14.0.0”
},
到我的package.json
。这确实使纱线列表jsdom
仅输出jsdom@14.1.0
,但我仍然得到相同的类型错误。解析到^15.0.0
会导致相同的错误,而解析到^16.0.0
会导致以下错误:
TypeError:this.dom.runVMScript不是函数
在JSDOMEnvironment.runScript(node_modules/jest-environment jsdom/build/index.js:187:23)
使用jest环境jsdom-*
我通过安装jest环境jsom 16
尝试了以下方法。更改package.json中的test
脚本并运行纱线测试--showConfig
会产生一系列信息,包括以下行:
“测试环境”:“//node\u modules/jest-environment jsdom十六/lib/index.js”,
如果我在测试中添加一个console.log(navigator.userAgent)
,我也会得到
Mozilla/5.0 (darwin) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/16.4.0
然而,我仍然得到相同的类型错误:MutationObserver不是构造函数
我还尝试了jest-environment-jsdom-14
和jest-environment-jsdom-15
,并在将jsdom
强制到^14.0.0
的同时进行了尝试。同样的结果
使用mutationobserver垫片
我运行了warn add-D mutationobserver shim
并在我的jestSetup.ts
中导入了它(使用import'mutationobserver shim'
)(这是我的Jest配置中的globalSetup
指向的内容),但这导致了以下错误:
ReferenceError:未定义窗口
反对。(//node_modules/mutationobserver shim/dist/mutationobserver.min.js:12:1)
将导入添加到我的测试文件会产生与上面相同的TypeError
,将console.log(global.MutationObserver)
添加到我的测试文件会产生未定义的
一个不太好的解决方案
经过多次尝试和错误,我发现如果1)安装了jest环境jsdom 16
并告诉jest使用它,2)在测试文件中添加import'mutationobserver shim'
,测试就会通过。但是,如果我将添加导入放在JestglobalSetup
文件中,它将不起作用。我得到了与以前相同的ReferenceError:window未定义错误
我的问题
如何在不要求组件库的用户向其所有测试文件中添加导入语句的情况下消除这两个错误?应该在setupfileafterenv
中应用polyfill,因为这是JSDOM环境实例化的地方,并且窗口
变得可用<代码>窗口
不应在globalSetup
中可用,因为它不在测试范围内运行
如果这是一个未被截取的create react app项目,则对应于setupfileafterenv
的安装文件是src/setupTests.ts
(src/setupTests.js
)
较新的jsdom
版本会导致错误,这意味着它与旧的Jest(jest@24
)。它们应该被弹出并升级,或者更新CRA(react)-scripts@4
)必须使用Jest 26支持。这确实消除了引用错误:未定义窗口,但现在我又回到另一个问题,即window.MutationObserver
没有从src/setupTests.ts
保留到实际测试。(我可以在两个位置添加console.log
语句,并查看它是在前者中定义的,而不是在后者中定义的。)您所描述的“back”是指哪种情况?我不确定这是怎么可能的。window.MutationObserver
也应该在测试中可用,因为setupTests和测试运行在同一范围内,除非您在测试文件中执行了某些操作,可能会像意外分配一样将其删除。在确认它在那里可用后,尝试在setupTests中将其设置为只读,Object.defineProperty(窗口,'MutationObserver',{writable:false,configurable:false,value:MutationObserver})
。确保不要对您的环境做任何奇怪的事情,如您提到的jest-environment jsdom-*
。是的,您是正确的。我后来在那个文件中找到了它:Object.defineProperty(窗口,'MutationObserver',{value:undefined})代码>就这样!拆下它解决了问题,我甚至不需要垫片。感谢您给我指出src/setupTests.ts
!
Mozilla/5.0 (darwin) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/16.4.0