React集成JointJS组件单元测试报xhtml未定义TypeError
问题:React集成JointJS组件单元测试报错TypeError: Cannot read properties of undefined (reading 'xhtml')
我正在为集成JointJS库的React组件编写单元测试用例,运行时抛出如下错误:
TypeError: Cannot read properties of undefined (reading 'xhtml') 175 | graphRef.current = graph; 176 | const tree = new joint.layout.TreeLayout({ graph: graph }); > 177 | const paper = new joint.dia.Paper({ | ^ 178 | width: width, 179 | height: height, 180 | model: graph, at child.xhtml [as children] (node_modules/@clientio/rappid/rappid.js:31722:31) at result (node_modules/lodash/lodash.js:13708:44) at child.result [as renderChildren] (node_modules/@clientio/rappid/rappid.js:18445:34) at child.renderChildren (node_modules/@clientio/rappid/rappid.js:31770:15) at child.apply [as render] (node_modules/@clientio/rappid/rappid.js:18696:27) at child.render [as init] (node_modules/@clientio/rappid/rappid.js:31572:15) at child.init [as initialize] (node_modules/@clientio/rappid/rappid.js:18433:15) at child.Backbone.View (node_modules/backbone/backbone.js:1310:21) at child.call [as constructor] (node_modules/@clientio/rappid/rappid.js:18425:24) at new child (node_modules/backbone/backbone.js:2070:41) at src/components/Configuration/SiteNavigation/SiteNavigation.tsx:177:19 at commitHookEffectListMount (node_modules/react-dom/cjs/react-dom.development.js:19731:26) at commitPassiveHookEffects (node_modules/react-dom/cjs/react-dom.development.js:19769:11) at HTMLUnknownElement.callCallback (node_modules/react-dom/cjs/react-dom.development.js:188:14) at HTMLUnknownElement.callTheUserObjectsOperation (node_modules/jsdom/lib/jsdom/living/generated/EventListener.js:26:30) at innerInvokeEventListeners (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:350:25) at invokeEventListeners (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:286:3) at HTMLUnknownElementImpl._dispatch (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:233:9) at HTMLUnknownElementImpl.dispatchEvent (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:104:17) at HTMLUnknownElement.dispatchEvent (node_modules/jsdom/lib/jsdom/living/generated/EventTarget.js:241:34) at Object.invokeGuardedCallbackDev (node_modules/react-dom/cjs/react-dom.development.js:237:16) at invokeGuardedCallback (node_modules/react-dom/cjs/react-dom.development.js:292:31) at flushPassiveEffectsImpl (node_modules/react-dom/cjs/react-dom.development.js:22853:9) at unstable_runWithPriority (node_modules/scheduler/cjs/scheduler.development.js:653:12) at runWithPriority$1 (node_modules/react-dom/cjs/react-dom.development.js:11039:10) at flushPassiveEffects (node_modules/react-dom/cjs/react-dom.development.js:22820:12) at Object.<anonymous>.flushWork (node_modules/react-dom/cjs/react-dom-test-utils.development.js:876:10) at act (node_modules/react-dom/cjs/react-dom-test-utils.development.js:994:9) at render (node_modules/@testing-library/react/dist/pure.js:97:26)
以下是组件初始渲染时,在useEffect钩子中声明graph和paper对象的代码:
const tree = new joint.layout.TreeLayout({ graph: graph }); const paper = new joint.dia.Paper({ width: width, height: height, model: graph, gridSize: 10, perpendicularLinks: false, drawGrid: { name: "mesh", args: { color: "#D3D4D5", scaleFactor: 4 } }, background: { color: "rgba(0, 255, 0, 0.0)", }, interactive: true, });
解决方案
这个错误源于joint.dia.Paper在测试环境(如jsdom)中缺少必要的DOM挂载节点或环境支持,可通过以下方式解决:
给Paper指定挂载容器
创建Paper实例时,添加el属性指向一个真实DOM元素。测试环境中可提前创建并挂载容器,测试后清理:// 在useEffect内或测试用例中添加 const container = document.createElement('div'); document.body.appendChild(container); const paper = new joint.dia.Paper({ el: container, // 新增挂载容器配置 width: width, height: height, model: graph, // 其他原有配置 }); // 测试结束后清理(可放在useEffect的清理函数中) return () => { document.body.removeChild(container); paper.remove(); };Mock JointJS的Paper类
若单元测试无需验证Paper渲染细节,直接Mockjoint.dia.Paper避免环境问题(以Jest为例):jest.mock('@clientio/rappid', () => { const original = jest.requireActual('@clientio/rappid'); return { ...original, dia: { ...original.dia, Paper: jest.fn().mockReturnValue({ // 模拟业务需要的Paper方法,比如remove、render等 remove: jest.fn(), render: jest.fn() }) }, layout: { TreeLayout: jest.fn() } }; });优化测试环境DOM配置
确保jsdom等测试环境支持SVG特性,在Jest配置文件中添加:{ "testEnvironmentOptions": { "resources": "usable", "runScripts": "dangerously" } }
内容的提问来源于stack exchange,提问作者Deepthy G
相关产品推荐
相关产品推荐

