Search code examples
typescriptts-jest

How to use OffscreenCanvas in Jest Typescript test?


I have a Typescript class with a instance variable reference to OffscreenCanvas:

foo.ts

export class Foo {
   private _canvas = new OffscreenCanvas(256, 256);
   ...
}

I'm trying to test the code in foo.ts using Jest with the following test:

import {describe, expect, test} from '@jest/globals';
import { Foo } from '../src/foo';

describe('foo module', function() {
    test('should test foo', () => {
        new Foo();
    });
});

This test is ran with ts-jest and executed using npx jest. When running the test, I see the following error output:

ReferenceError: OffscreenCanvas is not defined

      304 |
      305 | export class Foo {
    > 306 |     private _canvas = new OffscreenCanvas(256, 256);
          |                           ^
      307 | }
      308 |
      309 |

I suspect this is because browser features like OffscreenCanvas are not available since the test is executed using Node. My question is: is something like this possible without trying to mock out OffscreenCanvas? Any way to integrate node-canvas?

A couple of things tried so far: 1) Since it's complaining about it not being defined, I tried installing the types from @types/offscreencanvas and then adding them to types property in tsconfig.json:

...
"types": ["offscreencanvas"],
...

No luck with this. I also tried adding jest-canvas-mock to see if that would help, to no avail. Any help or pointer in the right direction would be helpful. Thanks.


Solution

  • Maybe this is not a perfect solutions, but its a working one. You can just add a Mock in the beforeEach of your Testsuite.

    beforeEach(async () => {
        window.OffscreenCanvas = jest.fn().mockImplementation((width: number, height: number) => {
            return {
                height,
                width,
                oncontextlost: jest.fn(),
                oncontextrestored: jest.fn(),
                getContext: jest.fn(() => undefined),
                convertToBlob: jest.fn(),
                transferToImageBitmap: jest.fn(),
                addEventListener: jest.fn(),
                removeEventListener: jest.fn(),
                dispatchEvent: jest.fn()
            } as unknown as OffscreenCanvas;
        });
    });
    

    Naturally it will return undefined on the following canvas.getContext("2d") call, which in my case leads to an expected error which i catch.