3

Trying to run yarn test and have tried many version of node (8 and 11), react (57,58), but cannot fix this error.

 FAIL  __tests__/index.ios.js
  ● Test suite failed to run

    /xyz/mobile-react/node_modules/react-native/jest/setup.js: babel-plugin-jest-hoist: The module factory of `jest.mock()` is not allowed to reference any out-of-scope variables.
    Invalid variable access: MockNativeMethods
    Whitelisted objects: Array, ArrayBuffer, Boolean, DataView, Date, Error, EvalError, Float32Array, Float64Array, Function, Generator, GeneratorFunction, Infinity, Int16Array, Int32Array, Int8Array, InternalError, Intl, JSON, Map, Math, NaN, Number, Object, Promise, Proxy, RangeError, ReferenceError, Reflect, RegExp, Set, String, Symbol, SyntaxError, TypeError, URIError, Uint16Array, Uint32Array, Uint8Array, Uint8ClampedArray, WeakMap, WeakSet, arguments, expect, jest, require, undefined, console, DTRACE_NET_SERVER_CONNECTION, DTRACE_NET_STREAM_END, DTRACE_HTTP_SERVER_REQUEST, DTRACE_HTTP_SERVER_RESPONSE, DTRACE_HTTP_CLIENT_REQUEST, DTRACE_HTTP_CLIENT_RESPONSE, global, process, Buffer, clearImmediate, clearInterval, clearTimeout, setImmediate, setInterval, setTimeout.
    Note: This is a precaution to guard against uninitialized mock variables. If it is ensured that the mock is required lazily, variable names prefixed with `mock` are permitted.

      at invariant (node_modules/babel-jest/node_modules/babel-plugin-jest-hoist/build/index.js:13:11)

package.json:

{
  "name": "XYZ",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "node node_modules/react-native/local-cli/cli.js start",
    "android-local": "ENVFILE=.env.local react-native run-android",
    "android-dev": "ENVFILE=.env.dev react-native run-android",
    "android-qa": "ENVFILE=.env.qa react-native run-android",
    "build-android-dev": "export ENVFILE=.env.dev && cd android && ./gradlew assembleRelease && cd ..",
    "build-android-qa": "export ENVFILE=.env.qa && cd android && ./gradlew assembleRelease && cd ..",
    "test": "jest"
  },
  "rnpm": {
    "assets": [
      "./assets/fonts/"
    ]
  },
  "dependencies": {
    "chai": "^4.1.2",
    "chai-http": "^4.0.0",
    "eslint-config-rallycoding": "^3.2.0",
    "fs": "0.0.1-security",
    "google-auth-library": "^0.11.0",
    "googleapis": "^22.2.0",
    "jetifier": "^1.6.4",
    "lodash": "^4.17.4",
    "moment": "^2.18.1",
    "node-fetch": "^2.1.2",
    "prop-types": "^15.5.10",
    "q": "^1.5.0",
    "react": "16.6.1",
    "react-native": "0.58",
    "react-native-android-location-enabler": "^1.0.5",
    "react-native-android-location-services-dialog-box": "^2.0.0",
    "react-native-config": "^0.6.1",
    "react-native-datepicker": "^1.6.0",
    "react-native-hockeyapp": "^0.5.3",
    "react-native-image-crop-picker": "^0.16.0",
    "react-native-image-resizer": "1.0.0",
    "react-native-localization": "^0.2.1",
    "react-native-maps": "^0.21.0",
    "react-native-tab-view": "0.0.75",
    "react-native-vector-icons": "6.1.0",
    "react-native-version-number": "^0.1.2",
    "react-navigation": "^1.0.0-beta.11",
    "react-navigation-redux-helpers": "^1.0.3",
    "react-redux": "^5.0.5",
    "readline": "^1.3.0",
    "redux": "^3.7.2",
    "redux-persist": "^5.9.1",
    "redux-thunk": "^2.2.0"
  },
  "devDependencies": {
    "babel-jest": "20.0.3",
    "babel-plugin-transform-object-rest-spread": "^7.0.0-beta.3",
    "babel-preset-jest": "22",
    "babel-preset-react-native": "4.0.1",
    "jest": "20.0.4",
    "mocha": "^5.1.1",
    "react-test-renderer": "16.0.0-alpha.12"
  },
  "jest": {
    "preset": "react-native"
  }
}

.babelrc

{
  "presets": ["react-native"]
}
skyboyer
  • 22,209
  • 7
  • 57
  • 64
thevikas
  • 1,618
  • 1
  • 14
  • 31
  • I am also facing the same issue, but this post was helped me. https://stackoverflow.com/a/46672690/13480806 – Akshay Pal Dec 10 '21 at 15:24

1 Answers1

11

Without seeing your exact code, it's hard to say what the problem is. However, the key is in the NOTE:

Note: This is a precaution to guard against uninitialized mock variables. If it is ensured that the mock is required lazily, variable names prefixed with mock are permitted.

The problem is that Jest mocks get hoisted to the top of the page. So, you can't reference a variable in your mocks... because the variable doesn't exist yet. See:

https://jestjs.io/docs/en/es6-class-mocks.html#calling-jestmock-docs-en-jest-object-jestmockmodulename-factory-options-with-the-module-factory-parameter

To overcome that, you need to do as the Note says, prefix your variable with the word "mock".

Here's an example where the import getAppPages needs to be overridden so that it returns a fake array (appPages)

import React from 'react';

import { getAppPages } from 'utils';
import App from './App';
import { fireEvent, render } from '../../../test/test-utils';
import appPages from '../../../__mocks__/data/appPages';

const mockAppPages = appPages;

jest.mock('utils', () => ({
  getAppPages: () => mockAppPages,
}));

describe('App', () => {
  test('renders and defaults to home page and matches snapshot', () => {
    ...
  });
});
Justin Noel
  • 5,945
  • 10
  • 44
  • 59