69

I am writing tests using Jest for components that use canvas elements. I keep getting an error when I run my tests that looks like this.

Error: Not implemented: HTMLCanvasElement.prototype.getContext (without installing the canvas npm package)

From my understanding Jest uses jsdom for its testing and that jsdom is compatible with canvas if you install the canvas or canvas-prebuilt packages.

I have tried installing each of these packages and neither of them have resolved the error. The only thing that I think could be going wrong is that jsdom cannot find the canvas or canvas-prebuilt packages. Does anyone know a way to fix this error or test to see if jsdom is finding the other packages? Thanks a lot!

skyboyer
  • 22,209
  • 7
  • 57
  • 64
lpie88
  • 753
  • 1
  • 5
  • 5

7 Answers7

85

My team is using create-react-app and we had previously addressed this problem by adding the npm package jest-canvas-mock. Now after upgrading to react-scripts 3.4.1, we also had to add a specific import to our src/setupTests.ts file:

import 'jest-canvas-mock';
PaulMest
  • 12,925
  • 7
  • 53
  • 50
54

You can create your own mock of the function in a jest setup script

HTMLCanvasElement.prototype.getContext = () => { 
  // return whatever getContext has to return
};
Red Mercury
  • 3,971
  • 1
  • 26
  • 32
  • This worked perfectly. I had tried to do something similar to this but it turns out I didn't include the path to the file in my setupFiles array. Thank you so much for your help! – lpie88 Feb 18 '18 at 14:06
  • 1
    Add this setup to your setupFile.js – nima Jul 12 '19 at 08:10
  • This stopped working for me with Jest 27 ("ReferenceError: HTMLCanvasElement is not defined"). Edit: adding `testEnvironment: "jsdom",` to jest.config.js fixed it. This was a default change in Jest 27: https://jestjs.io/blog/2021/05/25/jest-27 – forresto Aug 12 '21 at 08:03
  • You can also add this in individual test files. – DarkTrick Dec 06 '22 at 07:43
15

I had similar problem with my Jest tests, and solved it by installing jest-canvas-mock.

ElectroBuddha
  • 630
  • 10
  • 20
  • 10
    There's a few questions on Stack Overflow that are answered by "just install jest-canvas-mock and here's how to do 'setupFiles'". It'd be really helpful if those answers included a complete example test... just a trivial test would be fine but showing **how** jest-canvas-mock is used. – Andy Preston Nov 09 '20 at 12:25
  • 1
    I'm still encountering the same problem even after installing jest-canvas-mock and importing it in the test file. I'm using create-react-app – ionescho Aug 02 '22 at 13:57
13

I've solved it by installing jest-canvas-mock

npm i --save-dev jest-canvas-mock

And adding this configuration on package.json

{
  "jest": {
    "setupFiles": [
      "jest-canvas-mock"
    ],
  }
}
equiman
  • 7,810
  • 2
  • 45
  • 47
4

Both answers above work. However, just wanted to add that in case of create-react-app, it doesn't support the 'setupFiles' required by jest conf in package.json for jest-canvas-mock.

I got around this by adding the import statement in each of the test files that were invoking the canvas element(in my case 3). Then, I moved the import statement to the setupTests.js file and removed that requirement as well.

Amrita Yadav
  • 95
  • 1
  • 8
  • 1
    I'm also using create-react-app and didn't want to eject. I imported `import 'jest-canvas-mock'` in my setupTest.js alone, and so far it has seemed to work. – Jeff May 20 '20 at 20:05
4

you can create it as mock and you don't install a new package:

HTMLCanvasElement.prototype.getContext = jest.fn();
wes
  • 191
  • 1
  • 4
0

I experienced the same problem using react-scripts 3.0.1 and solved it by installing jest-canvas-mock as a dev dependency and importing it (import 'jest-canvas-mock') on my app.test.js file (where I got that error from) only as importing it on setupTests.js would unnecessarily import the package in every single test file.

sgtbrunner
  • 31
  • 5