最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - "TypeError: cannot read property 'prototype' of undefined" when Jest testing reac

programmeradmin6浏览0评论

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.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论