Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Export mock factory functions for Chrome types #14

Open
p00ya opened this issue Feb 10, 2022 · 0 comments
Open

Export mock factory functions for Chrome types #14

p00ya opened this issue Feb 10, 2022 · 0 comments

Comments

@p00ya
Copy link

p00ya commented Feb 10, 2022

Is your feature request related to a problem? Please describe.

Provide a factory for chrome.runtime.Port.

Consider trying to test code that calls chrome.runtime.connect:

const mockConnect = (extensionId?: string, connectInfo?: object) => {
  const port: chrome.runtime.Port = {
    name: connectionInfo?.name ?? 'name',
    postMessage: jest.fn() as jest.MockedFunction<(message: any) => void>,
    disconnect: jest.fn() as jest.MockedFunction<() => void>,
    onDisconnect,  // Event is non-trivial to fake!
    onMessage,  // another Event :(
  };
  return port;
};

chrome.runtime.connect.mockImplementation(mockConnect);

Creating a suitable mock implementation is quite arduous in typescript (Port itself has onMessage and onDisconnect events, and they in turn have a bunch of their own methods that need to be mocked).

jest-chrome already mocks a bunch of things like this, but only for the static functions in the Chrome API. It has the necessary machinery to make mocking events (and even schema-driven mocking) easy, but it neither applies that to things like Port, nor does it expose functions like createEvent.

Describe the solution you'd like

jest-chrome should export a chromeMocks like:

import { chromeMocks } from 'jest-chrome';

const port = new chromeMocks.runtime.Port();
chrome.runtime.connect.mockReturnValue(port);

codeUnderTest();

// Events on the Port mock are just as easy to use as `chrome.runtime.onMessage`.
const listenerSpy = jest.fn();
port.onMessage.addListener(listenerSpy);

Describe alternatives you've considered

Manually mock

i.e. try and finish the code in the mockConnect code in the first section. It's very tedious.

Call-oriented API

A slightly different API than above, instead of factories that return Chrome types like Port, use factories that correspond directly to the synchronous functions that would otherwise return types like Port.

Expose internal helpers

Instead of exposing a factory, jest-chrome could just expose its helpers like createEvent. However, then you'd be exporting APIs that didn't just come from Chrome, and it would make the implementation brittle (since you'd have to support these functions for compatibility going-forwards).

TBH though, just exporting the Event fakes would help a lot with users being able to mock things like Port.

Other mocking packages

I think something like jest-mock-extended would make mocking these types much less tedious. It can already do a lot of what jest-chrome does (but not the Event fakes).

Additional context

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant