简体   繁体   中英

Mock WebAPI interface using ts-mockito

I'm writing a unit test for a class which uses browser WebAPI interface .
I use ts-mockito to mock the interface (a WebGL2RenderingContext in my case).

When I run the test, Node throws ReferenceError: WebGL2RenderingContext is not defined which is understandable, because the test is run under NodeJS environment, not browser, so the class/interface doesn't exist.

Is there any way to make NodeJS environment aware of the WebAPI interfaces, so that it's possible to be mocked?

NOTE : Since it's a unit test, it should NOT be run on a real browser.
jsdom seems to be a possible solution, but I have no idea how to mock it with ts-mockito.


The following snippet illustrate what I'm trying to do:

import { mock, instance, verify } from 'ts-mockito'

// ========== CLASS ==========
class DummyClass {
    dummyMethod() : void {}
}

class TestedClass {
    static testDummy(dummy : DummyClass) : void {
        dummy.dummyMethod();
    }

    static testGlCtx(glCtx : WebGL2RenderingContext) : void {
        glCtx.flush();
    }
}

// ========== TEST ==========
describe('DummyClass', () => {
    // This test passed successfully
    it('works fine', () => {
        const mockDummy = mock(DummyClass);

        TestedClass.testDummy( instance(mockDummy) );

        verify( mockDummy.dummyMethod() ).once();
    });
});

describe('WebGL interface', () => {
    it('works fine', () => {
        // This line failed with 'ReferenceError: WebGL2RenderingContext is not defined'
        const mockGLCtx = mock(WebGL2RenderingContext);

        TestedClass.testGlCtx( instance(mockGLCtx) );

        verify( mockGLCtx.flush() ).once();
    });
});

Run using mocha with the command mocha --require ts-node/register 'test.ts' .

There are two solutions: For common DOM APIs, and for generic mocking.

For common DOM APIs

As detailed in this StackOverflow answer , jsdom can be used to bring DOM APIs into NodeJS runtime environment.

Run npm install --save-dev jsdom global-jsdom
and change Mocha's command to

mocha --require ts-node/register --require global-jsdom/register 'test.ts'

NOTE : global-jsdom is the newer & updated version of jsdom-global .

This solution works for common DOM APIs (such as HTMLElement , SVGElement , File ),
but it doesn't work for more specialized APIs (WebGL, Crypto, audio & video).

For generic interface mocking

Turns out ts-mockito has a way to mock interfaces , including DOM & any browser Web APIs.

So the above test code can be changed to:

describe('WebGL interface', () => {
    it('works fine', () => {
        const mockGLCtx = mock<WebGL2RenderingContext>();

        TestedClass.testGlCtx( instance(mockGLCtx) );

        verify( mockGLCtx.flush() ).once();
    });
});

and the test will run successfully.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM