Reputation: 11
I'm trying to write Unit test cases for a React component containing jointJs library it is throwing below error. How to solve this error ?
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)
This is how we declared graph object and paper object in UseEffect hook which will be called on intial render of the component
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,
});
Upvotes: 0
Views: 530
Reputation: 143
You need to first mock your method before running any assertions. Something like this -
jest.mock("jointjs", () => {
return {
dia: {
Paper: jest.fn().mockImplementation(() => {
width: 100,
height: 100,
model: graph,
gridSize: 10,
perpendicularLinks: false,
drawGrid: {
name: "mesh",
args: {
color: "#D3D4D5",
scaleFactor: 4
}
},
background: {
color: "rgba(0, 255, 0, 0.0)",
},
interactive: true,
})
}
}
})
And then have add your required assertions. I am assuming you are using react testing library. E.g.
test("Render element", async () => {
render(<Your component />);
await waitFor(() => {
expect(your method).toBeTruthy();
});
For reference, these docs may help:
Upvotes: 1
Reputation: 336
Jest uses JSDOM which doesn't support a lot of SVG APIs. It is necessary to mock some functionality.
To fix this error, you can add the following to your tests setup file.
// Mock SVGAngle which is used for sanity checks in Vectorizer library
Object.defineProperty(window, 'SVGAngle', {
writable: true,
value: jest.fn().mockImplementation(() => ({
new: jest.fn(),
prototype: jest.fn(),
SVG_ANGLETYPE_UNKNOWN: 0,
SVG_ANGLETYPE_UNSPECIFIED: 1,
SVG_ANGLETYPE_DEG: 2,
SVG_ANGLETYPE_RAD: 3,
SVG_ANGLETYPE_GRAD: 4
}))
});
You can see an example of some mocks for Jest here: https://github.com/clientIO/joint-plus-tutorial-react/blob/main/src/setupTests.ts
Upvotes: 0