Reputation: 43
I have a react component that imports c3 and builds a c3 chart. Works fine, I can see the c3 chart.
I'm trying to test my react code with Jest, so I started a simple test for my react component, just an import for the component and test that verifies the component is 'truthy' (not null/not undefined), but I'm getting the following error when trying to run the test:
● Test suite failed to run
TypeError: Cannot read property 'prototype' of undefined
at node_modules/c3/c3.js:3578:29
at node_modules/c3/c3.js:4266:5
at node_modules/c3/c3.js:3:83
at Object.<anonymous> (node_modules/c3/c3.js:6:2)
at Object.<anonymous> (src/ChartPanel.tsx:2075:49)
at Object.<anonymous> (src/module.ts:131:25)
at Object.<anonymous> (src/module.test.ts:1:1)
Any idea? What am I missing here?
Example: Here is code using a react sample app, just modified it to include a custom component with simple c3 chart:
App.js
import React from 'react';
import './App.css';
import { Chart } from './Chart';
function App() {
return (
<div className="App">
<div className="App-link-container">
<a className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer">
Learn React
</a>
</div>
<Chart />
</div>
);
}
export default App;
Chart.js (component with very simple c3 chart)
import React, { PureComponent } from 'react';
import c3 from 'c3';
export class Chart extends PureComponent {
_chart;
componentDidMount() {
this._renderChart();
}
componentDidUpdate() {
this._renderChart();
}
_renderChart() {
this._chart = c3.generate({
bindto: '#chart',
data: {
columns: [
['data1', 30, 200, 100, 400, 150, 250],
['data2', 50, 20, 10, 40, 15, 25]
]
}
});
}
render() {
return <div id="chart">hi</div>;
}
}
Test (just verifying the 'Learn React' link is on the document. Seems the error is already fired in the import of the Chart component at the App.js)
import React from 'react';
import { render } from '@testing-library/react';
import App from './App';
test('renders learn react link', () => {
const { getByText } = render(<App />);
const linkElement = getByText(/learn react/i);
expect(linkElement).toBeInTheDocument();
});
Jest configured in package.json as following
"jest": {
"roots": [
"<rootDir>/src"
],
"collectCoverageFrom": [
"src/**/*.{js,jsx,ts,tsx}",
"!src/**/*.d.ts"
],
"setupFiles": [
"react-app-polyfill/jsdom"
],
"setupFilesAfterEnv": [
"<rootDir>/src/setupTests.js"
],
"testMatch": [
"<rootDir>/src/**/__tests__/**/*.{js,jsx,ts,tsx}",
"<rootDir>/src/**/*.{spec,test}.{js,jsx,ts,tsx}"
],
"testEnvironment": "jest-environment-jsdom-fourteen",
"transform": {
"^.+\\.(js|jsx|ts|tsx)$": "<rootDir>/node_modules/babel-jest"
},
"transformIgnorePatterns": [
"[/\\\\]node_modules[/\\\\].+\\.(js|jsx|ts|tsx)$",
"^.+\\.module\\.(css|sass|scss)$"
],
"modulePaths": [],
"moduleNameMapper": {
"^react-native$": "react-native-web",
"^.+\\.module\\.(css|sass|scss)$": "identity-obj-proxy"
},
"moduleFileExtensions": [
"web.js",
"js",
"web.ts",
"ts",
"web.tsx",
"tsx",
"json",
"web.jsx",
"jsx",
"node"
],
"watchPlugins": [
"jest-watch-typeahead/filename",
"jest-watch-typeahead/testname"
]
}
While setupTests.js has nothing special but the following line
import '@testing-library/jest-dom/extend-expect';
Upvotes: 4
Views: 3560
Reputation: 1091
There is a similar issue: https://github.com/thymikee/jest-preset-angular/issues/113
This is because jsdom doesn't provide an implementation for svg related api. If you follow the stacktrace to c3.js, you will find it is pointing right to
you just need to provide the stub c3 need in setupTests.js
:
window.SVGPathElement = jest.fn();
A side note: it is better to put setupTests.js
somewhere else so that it will not get compiled or published.
Upvotes: 8