How to correctly mock a React Native module that u

2019-07-23 18:58发布

问题:

I'm building a React Native app with TypeScript. I'm using react-native-firebase for my notifications. I'm furthermore using Jest and Enzyme for my unit tests.

I have the following wrapper function to check the users permissions:

export const checkPermissions = (): Promise<boolean> =>
  new Promise((resolve, reject) => {
    firebase
      .messaging()
      .hasPermission()
      .then(enabled => {
        if (enabled) {
          resolve(enabled);
        } else {
          firebase
            .messaging()
            .requestPermission()
            .then(resolve)
            .catch(reject);
        }
      });
  });

Now I want to test if the function gets called.

Here is the test I wrote:

import * as firebase from "react-native-firebase";
import { checkPermissions } from "./notificationHelpers";

jest.mock("react-native-firebase");

describe("checkPermissions", () => {
  beforeEach(async done => {
    jest.resetAllMocks();
    await checkPermissions();
    done();
  });

  it("should call firebase.messaging().hasPermission()", () => {
    expect(firebase.messaging().hasPermission).toHaveBeenCalledTimes(1);
  });
});

This throws the error:

 FAIL  app/services/utils/core/notificationHelpers/notificationHelpers.test.ts
  ● Test suite failed to run

    RNFirebase core module was not found natively on iOS, ensure you have correctly included the RNFirebase pod in your projects `Podfile` and have run `podinstall`.

     See http://invertase.link/ios for the ios setup guide.

      Error: RNFirebase core module was not found natively on iOS, ensure you have correctly included the RNFirebase pod in your projects `Podfile` and haverun `pod install`.

So it seems to me that modules that use native code can't simply by auto-mocked.

So I tried to manually mock it. Inside a folder __mocks__ that's within my root project adjacent to node_modules I created a file called react-native-firebase.ts, which looks like this:

const firebase = {
  messaging: jest.fn(() => ({
    hasPermission: jest.fn(() => new Promise(resolve => resolve(true)))
  }))
};

export default firebase;

But this code also fails, because firebase.messaging is allegedly undefined.

How would one test this stuff?