admin管理员组

文章数量:1390460

I have a react ponent 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 ponent, just an import for the ponent and test that verifies the ponent 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 ponent 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=""
           target="_blank"
           rel="noopener noreferrer">
           Learn React
        </a>
      </div>
      <Chart />
    </div>
  );
}
export default App;

Chart.js (ponent with very simple c3 chart)

import React, { PureComponent } from 'react';
import c3 from 'c3';

export class Chart extends PureComponent {
  _chart;

  ponentDidMount() {
    this._renderChart();
  }

  ponentDidUpdate() {
    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 ponent 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';

I have a react ponent 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 ponent, just an import for the ponent and test that verifies the ponent 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 ponent 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"
           target="_blank"
           rel="noopener noreferrer">
           Learn React
        </a>
      </div>
      <Chart />
    </div>
  );
}
export default App;

Chart.js (ponent with very simple c3 chart)

import React, { PureComponent } from 'react';
import c3 from 'c3';

export class Chart extends PureComponent {
  _chart;

  ponentDidMount() {
    this._renderChart();
  }

  ponentDidUpdate() {
    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 ponent 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';
Share edited May 26, 2020 at 12:44 WhiteMountain asked May 24, 2020 at 12:43 WhiteMountainWhiteMountain 431 silver badge4 bronze badges 6
  • 1 Please provide some code you have – Dlucidone Commented May 24, 2020 at 12:49
  • @Dlucidone, Thanks for looking into this. I've added a sample code where the issue is reproduced. – WhiteMountain Commented May 25, 2020 at 15:25
  • Please also provide jest.config.js – seanplwong Commented May 25, 2020 at 17:44
  • @seanplwong updated – WhiteMountain Commented May 26, 2020 at 12:52
  • did you solve this? – Ravindra Thorat Commented Feb 12, 2021 at 13:42
 |  Show 1 more ment

1 Answer 1

Reset to default 8

There is a similar issue: https://github./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 piled or published.

本文标签: