David Gevorgyan
David Gevorgyan

Reputation: 332

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'
    ...
}

Upvotes: 3

Views: 1201

Answers (1)

David Gevorgyan
David Gevorgyan

Reputation: 332

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 {};
});

Upvotes: 1

Related Questions