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?
Here is a way you can test code that depends on
react-native-firebase
Create a manual mock just by adding an empty file in
__mocks__/react-native-firebase.js
, mocks folder should be at the same level asnode_modules
as explained in jest docs specifically Mocking Node modules section.With this manual mock you avoid the error
Then you don't need
jest.mock("react-native-firebase");
also you don't need to testexpect(firebase.messaging().hasPermission).toHaveBeenCalledTimes(1);
What you can do instead is isolate the code that depends on
react-native-firebase
on small functions and then spy on those adding known results.For example, this verifyPhone function that depends on react-native-firebase.
To test code that depends on
verifyPhoneNumber
function you spy it and replace its implementation like this.I hope it helps!