Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Platform specific testing of react native with jest

The RN project I'm working on is intended as "android only", so there was no need to add libraries like "react-native-firebase" with cocoapods. I have to mention beforehand that I don't have access to any mac or macbook to do that. Here are snippets from package.json

...
"scripts": {
  "test": "jest"
},
"jest": {
  "preset": "react-native"
},
...

and babel.config.js

module.exports = {
    presets: [
      [
        'module:metro-react-native-babel-preset',
        {
          targets: {
            node: 'current',
          },
          loose: true,
          modules: 'auto',
        },
      ],
    ],
  };

A dummy function for jest testing:

// testing jest
const generateText = (name, age) => {
  return `${name} (${age} years old)`;
};

And the unit test for it:

import { generateText } from '../actions/authActions';

test('Some test', () => {
  const text = generateText('Zuul', 300);
  expect(text).toBe('Zuul (300 years old)');
});

With all this setup running yarn test gives this output:

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

The question is, is there a way to make jest skip ios-related checks and focus only on android stuff?

Update: Apparently there is a way to override the jest presets, so I added this to package.json:

"jest": {
  "preset": "react-native",
  "haste": {
    "defaultPlatform": "android",
    "platforms": [
      "android",
      "ios",
      "native"
    ],
    "providesModuleNodeModules": [
      "react-native"
    ]
  }
},

Now I have this error message:

RNFirebase core module was not found natively on Android,
ensure you have correctly added the RNFirebase and Firebase
gradle dependencies to your `android/app/build.gradle` file.

Which is simply not the case because all required dependencies were added to build.gradle:

dependencies {
    ...
    implementation project(':react-native-firebase')
    // Firebase dependencies
    implementation "com.google.android.gms:play-services-base:16.0.1"
    implementation "com.google.firebase:firebase-core:16.0.6"
    implementation('com.crashlytics.sdk.android:crashlytics:2.9.5@aar') {
        transitive = true
    }
    implementation "com.google.firebase:firebase-messaging:17.3.4"
    implementation 'me.leolin:ShortcutBadger:1.1.21@aar'
    ...
}
like image 904
David Gevorgyan Avatar asked Mar 19 '26 12:03

David Gevorgyan


1 Answers

Apparently it's a well known problem. I found the solution here. Basically I moved jest settings from package.json to jest.config.js:

//jest.config.js
module.exports = {
  preset: 'react-native',
  haste: {
    defaultPlatform: 'android',
    platforms: [
      'android',
      'ios',
      'native',
    ],
    providesModuleNodeModules: [
      'react-native',
    ],
  },
  setupFilesAfterEnv: ['./src/__mocks__/mockNativeLibs.js'],
  automock: false,
  moduleNameMapper: {
    '\\.(css|less)$': 'identity-obj-proxy',
    '^.+\\.(jpg|jpeg|gif|png|mp4|mkv|avi|webm|swf|wav|mid)$': 'jest-static-stubs/$1',
  },
  globals: {
    __DEV__: true,
  },
  collectCoverageFrom: [
    '**/src/**/*.{js,jsx}',
    '!**/src/**/style.js',
    '!**/src/**/index.js',
    '!**/src/theme/**',
    '!**/android/**',
    '!**/ios/**',
    '!**/node_modules/**',
    '!**/scripts/**',
    '!**/__test__/**',
  ],
  verbose: true,
  testPathIgnorePatterns: ['/node_modules/'],
};

and added this file:

//mockNativeLibs.js
jest.mock('react-native-firebase', () => {
  return {
    messaging: jest.fn(() => {
      return {
        hasPermission: jest.fn(() => Promise.resolve(true)),
        subscribeToTopic: jest.fn(),
        unsubscribeFromTopic: jest.fn(),
        requestPermission: jest.fn(() => Promise.resolve(true)),
        getToken: jest.fn(() => Promise.resolve('myMockToken')),
      };
    }),
    notifications: jest.fn(() => {
      return {
        onNotification: jest.fn(),
        onNotificationDisplayed: jest.fn(),
      };
    }),
    crashlytics: jest.fn(() => {
      return {
        recordError: jest.fn(),
      };
    }),
  };
});

// apparently there were more libraries causing problems with jest
jest.mock('pushy-react-native', () => {
  return {};
});

jest.mock('react-native-localize', () => {
  return {};
});

jest.mock('react-native-sound', () => {
  return {};
});
like image 92
David Gevorgyan Avatar answered Mar 21 '26 01:03

David Gevorgyan