C3: Unable to require() to use with Jest

Created on 7 Aug 2017  ·  13Comments  ·  Source: c3js/c3

TypeError: Cannot read property 'prototype' of undefined

      at ../../../../node_modules/c3/c3.js:2720:30
      at ../../../../node_modules/c3/c3.js:3263:3
      at Object.<anonymous>.CLASS.target (../../../../node_modules/c3/c3.js:2:82)
      at Object.<anonymous> (../../../../node_modules/c3/c3.js:5:2)

which is

        window.SVGPathElement.prototype.createSVGPathSegClosePath = function () {

I'm not quite sure where to report this. Jest, jsdom, here?

Most helpful comment

@fernandes Got it. I played around with it a bit more and was able to run the snapshot tests by mocking c3:

// __mocks__/c3.js
module.exports = () => 'c3';

and then in the Jest config portion of my package.json:

"moduleNameMapper": {
  "c3": "<rootDir>/__mocks__/c3.js",
}

All 13 comments

I'm also getting this error, not sure if it's a problem with c3 or jsdom.

Create an empty npm project. Then, try this:

npm i -S c3 jsom
node -e "var JSDOM = require('jsdom').JSDOM; global.window = new JSDOM().window; require('c3');"

Output:

/home/herinson/example/node_modules/c3/c3.js:2720
        window.SVGPathElement.prototype.createSVGPathSegClosePath = function () {
                             ^

TypeError: Cannot read property 'prototype' of undefined
    at /home/herinson/example/node_modules/c3/c3.js:2720:30
    at /home/herinson/example/node_modules/c3/c3.js:3263:3
    at CLASS.target (/home/herinson/example/node_modules/c3/c3.js:2:82)
    at Object.<anonymous> (/home/herinson/example/node_modules/c3/c3.js:5:2)
    at Module._compile (module.js:573:30)
    at Object.Module._extensions..js (module.js:584:10)
    at Module.load (module.js:507:32)
    at tryModuleLoad (module.js:470:12)
    at Function.Module._load (module.js:462:3)
    at Module.require (module.js:517:17)

I wasn't getting this error before.
Probably related to this https://github.com/tmpvar/jsdom/pull/1445

Do you think we can just mock the SVGPathElement property?

I think it's obviously a problem with jsdom's incomplete SVG implementation (which I don't blame them for; that shit sounds like it sucks)

However, what would be a good workaround? I want to be able to unit test a project that has C3 as a dependency with jsdom/jest, but this is a pretty big blocker. I don't actually need to unit test any of the C3 functionality so I guess I could stub it out...

Do you think we can just mock the SVGPathElement property?

That would be a possible solution.

I'm not even using c3, but probably other packages of my project are.
My tests were working fine until I updated a bunch of dependencies. I'm still trying to figure out what dependency is using c3.
PS: jsdom is present in my tests files.

Found it! Rolling keen-js back to v3.4.1 "solved" the problem. Latest version is 4.0.0.

In case of anyone with the same issue as mine, Keen decided to divide their main package into 3 separated packages: https://github.com/keen/keen-js/releases/tag/v4.0.0

The problem is that keen-dataviz.js uses c3.js. I'm not using charts, so for my case the solution is to install keen-tracking and remove keen-js.

I'm facing the same problem using jest, and trying to snapshot a component that uses react-c3js

    TypeError: Cannot read property 'prototype' of undefined

      at node_modules/c3/c3.js:2806:30
      at node_modules/c3/c3.js:3349:3

just some differences on line number, probably some build related (I'm using c3 version : 0.4.18)

update: window.SVGPathElement.prototype.createSVGPathSegClosePath = function () is the line here too

ps: works perfectly on browser, just on jest happens this error

Same here. I believe this one answers why: https://github.com/tmpvar/jsdom/issues/1423

@brandonros
If you don't need c3 functionality in your jest test cases, I think it's ok to replace SVGPathElement with dummy object.

I was able to require c3.js in node environment by dummying window.SVGPathElement like the below:

var JSDOM = require('jsdom').JSDOM;
global.window = new JSDOM().window;
window.SVGPathElement = function () {};
console.log(require('c3')); // => no error!

@fernandes I'm facing a similar problem. Have you been able to find a workaround?

hi @esonmez , I hadn't...

as I've researched jsdom doesn't implement the SVG stuff on it, that's why can't use c3 on tests (that uses jdsom), I just isolated the c3 component as much as I could and dropped this test heheh

@fernandes Got it. I played around with it a bit more and was able to run the snapshot tests by mocking c3:

// __mocks__/c3.js
module.exports = () => 'c3';

and then in the Jest config portion of my package.json:

"moduleNameMapper": {
  "c3": "<rootDir>/__mocks__/c3.js",
}

hahaha that's interesting, thanks for sharing the tip, I'm gonna implement on my project, thank you!

I was excited to solve this using @esonmez's suggestion, but since the project I'm working on leverages create-react-app, I got stuck again:

Out of the box, Create React App only supports overriding these Jest options:

  • collectCoverageFrom
  • coverageReporters
  • coverageThreshold
  • snapshotSerializers.

These options in your package.json Jest configuration are not currently supported by Create React App:

  • moduleNameMapper

If you wish to override other Jest options, you need to eject from the default setup. You can do so by running npm run eject but remember that this is a one-way operation. You may also file an issue with Create React App to discuss supporting more options out of the box.

Frustrating to say the least. In any case, in our jest setup file, I was able to mock it just like @kt3k did:

global.SVGPathElement = function () {}

And that worked like a charm. Thanks for the help all!

For questions involving the interplay between C3.js and any other library (react, vuejs, ..) please use the Google Group at https://groups.google.com/forum/#!forum/c3js.

Thank you!

Was this page helpful?
0 / 5 - 0 ratings