thevikas
thevikas

Reputation: 1639

Getting error while jest: The module factory of `jest.mock()` is not allowed to reference any out-of-scope variables

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"]
}

Upvotes: 3

Views: 12240

Answers (1)

Justin Noel
Justin Noel

Reputation: 6205

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', () => {
    ...
  });
});

Upvotes: 12

Related Questions