'@react-native-firebase breaking unit tests

I installed v6 of @react-native-firebase, it's working as expected but when I try to run a unit test I get the following error:

Jest encountered an unexpected token

Details:

/node_modules/@react-native-firebase/database/lib/index.js:18
import { isBoolean, isNumber, isString } from '@react-native-firebase/app/lib/common';
       ^

SyntaxError: Unexpected token {

I tried adding @react-native-firebase/database & @react-native-firebase/app to jest config transformIgnorePatterns and get the following error:

Test suite failed to run

Invariant Violation: Native module cannot be null.

  at invariant (node_modules/invariant/invariant.js:40:15)
  at RNFBNativeEventEmitter.NativeEventEmitter (node_modules/react-native/Libraries/EventEmitter/NativeEventEmitter.js:36:7)
  at new RNFBNativeEventEmitter (node_modules/@react-native-firebase/app/lib/internal/RNFBNativeEventEmitter.js:24:5)
  at Object.<anonymous> (node_modules/@react-native-firebase/app/lib/internal/RNFBNativeEventEmitter.js:48:16)
  at Object.<anonymous> (node_modules/@react-native-firebase/app/lib/internal/registry/nativeModule.js:21:1)

I also tried mocking the module with Jest like so:

import * as FBCommon from '@react-native-firebase/app/lib/common'

jest.mock(FBCommon, () => {
return () => ({
    isBoolean: jest.fn(),
    isNumber: jest.fn(),
    isString: jest.fn()
  })
});

and like this:

jest.mock('@react-native-firebase/database', () => {
   return () => ({
     ref: jest.fn()
   })
 }); 

but get the same error, any suggestions?

my package.json:

{
  "name": "Project",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "android": "react-native run-android",
    "ios": "react-native run-ios",
    "start": "react-native start",
    "test": "jest",
    "lint": "eslint ."
  },
  "dependencies": {
    "@react-native-community/push-notification-ios": "^1.0.6",
    "@react-native-firebase/app": "^6.3.1",
    "@react-native-firebase/database": "^6.3.1",
    "@react-native-firebase/messaging": "^6.3.1",
    "axios": "^0.19.0",
    "base-64": "^0.1.0",
    "blinkid-react-native": "^5.2.0",
    "firebase": "^7.6.0",
    "lodash": "^4.17.15",
    "mobx": "^5.15.0",
    "mobx-persist": "^0.4.1",
    "mobx-react": "^6.1.4",
    "react": "16.9.0",
    "react-native": "0.61.4",
    "react-native-auth0": "^2.1.0",
    "react-native-collapsible": "^1.5.1",
    "react-native-config": "^0.12.0",
    "react-native-confirmation-code-input": "^1.0.4",
    "react-native-datepicker": "^1.7.2",
    "react-native-device-info": "^5.4.1",
    "react-native-elements": "^1.2.7",
    "react-native-freshchat-sdk": "^2.3.0",
    "react-native-gesture-handler": "^1.5.2",
    "react-native-in-app-notification": "^3.0.1",
    "react-native-keyboard-aware-scroll-view": "^0.9.1",
    "react-native-phone-input": "^0.2.4",
    "react-native-picker-select": "^6.3.3",
    "react-native-push-notification": "^3.1.9",
    "react-native-reanimated": "^1.4.0",
    "react-native-screens": "^1.0.0-alpha.23",
    "react-native-signature-capture": "^0.4.10",
    "react-native-vector-icons": "^6.6.0",
    "react-native-webview": "^8.0.3",
    "react-navigation": "^4.0.10",
    "react-navigation-stack": "^1.10.3"
  },
  "devDependencies": {
    "@babel/core": "^7.7.2",
    "@babel/runtime": "^7.7.2",
    "@react-native-community/eslint-config": "^0.0.5",
    "babel-jest": "^24.9.0",
    "babel-plugin-module-resolver": "^4.0.0",
    "chai": "^4.1.2",
    "chai-enzyme": "1.0.0-beta.0",
    "enzyme": "^3.3.0",
    "enzyme-adapter-react-16": "^1.1.1",
    "eslint": "^6.6.0",
    "jest": "^24.9.0",
    "jsdom": "15.2.1",
    "jsdom-global": "3.0.2",
    "metro-react-native-babel-preset": "^0.57.0",
    "react-dom": "^16.12.0",
    "react-test-renderer": "16.9.0",
    "sinon": "^7.2.2"
  },
  "jest": {
    "preset": "react-native",
    "setupFilesAfterEnv": [
      "./setUpTests.js"
    ],
    "transformIgnorePatterns": [
      "node_modules/(?!((jest-)?react-native|@react-native-firebase/database|@react-native-firebase/app|react-clone-referenced-element|expo(nent)?|@expo(nent)?/.*|react-navigation|@react-navigation/.*|sentry-expo|native-base))"
    ]
  }
}


Solution 1:[1]

You could mock firebase database by creating a mock module in a mocks directory like this:

mkdir -p __mocks__/@react-native-firebase/database
touch index.js

And use jest mocking functions in index.js for the firebase version and database functionalities to test. Something along these lines:

const database = {
  functionality1: jest.fn(() => ({
    propertyExample1: jest.fn(() => Promise.resolve(true)),
    ...
  })),
  ...
  functionality2: jest.fn(() => ({
     property2: jest.fn(() => Promise.resolve(true)),...
  })),
};

export default database;

Solution 2:[2]

This occurs because the native emitter isn't properly mocked by the library. Adding the following snippet at the top of your tests can resolve this by ensuring the module isn't null.

jest.mock('react-native/Libraries/EventEmitter/NativeEventEmitter');

Solution 3:[3]

I solved the issue creating jest.setup.js file with the content:

jest.mock('react-native/Libraries/EventEmitter/NativeEventEmitter');

And then in package.json inside jest

"setupFiles": ["./yourPath/jest.setup.js"],

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Natalie
Solution 3 Glenn Andrés P. Rosario