babel-plugin-rewire icon indicating copy to clipboard operation
babel-plugin-rewire copied to clipboard

Jest test on function that's not exported

Open techrah opened this issue 7 years ago • 18 comments

I'm trying to do unit tests using Jest on a function that is not exported. I'm unable to use Rewire because I'm in a React Native environment with babel. I only want to get the function but I can't figure this out from the documentation. For example, let's say I have a file file.js that has a function foo. How do I reference this function from my test file.

file.js:

function foo() {
  ...
}

file.tests.js:

// how do I __get__ foo?

Thanks!

techrah avatar Feb 28 '17 22:02 techrah

in file.spec.js you should be able to do

import file from './file';

const foo = file.__get__('foo');
const returnValueOfFoo = foo(params)

Tmassery avatar Mar 03 '17 20:03 Tmassery

I'm currently not able to get past the import presumably due to improper configuration. Currently I have Jest configured to work with Babel in my setup. Then, I've configured Babel to work with this plugin via .babel.rc like this:

{
  "presets": ["react-native"],
  "plugins": [
    "transform-object-rest-spread",
    "rewire"
  ]
}

However, I'm getting the following error when I npm test, generated by the import line:

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: _get__
    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, 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, console, 0.706316033888597, __core-js_shared__.
    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-plugin-jest-hoist/build/index.js:13:11)

Note:

  • This has nothing to do with the __get__ line in your example; jest never gets that far.
  • It's complaining about _get__ with a single underscore before 'get'; weird.

techrah avatar Mar 04 '17 18:03 techrah

@ryanhomer try:

{
  "presets": [
    "es2015",
    "stage-0"
  ],
  "env": {
    "test": {
      "plugins": [
        "istanbul",
        "babel-plugin-rewire"
      ]
    }
  }
}

Tmassery avatar Mar 06 '17 04:03 Tmassery

Looks like stage-0 is no longer a built-in option so I had to npm install babel-preset-stage-0 --save-dev then add babel-preset-stage-0 to presets instead.

It took about 3 seconds longer than before to throw the error but I'm still getting the same error. Any further suggestions are appreciated.

Thanks.

techrah avatar Mar 06 '17 14:03 techrah

@ryanhomer did you add istanbul and switch your rewire to babel-install-rewire?

Tmassery avatar Mar 06 '17 16:03 Tmassery

Yes, I copied/pasted the "env" section exactly as is. For the "presets" section, I tried several combinations of react-native, es2015 and babel-preset-stage-0.

techrah avatar Mar 07 '17 18:03 techrah

@ryanhomer oh it looks like it doesn't like your use of babel-plugin-jest-hoist, try uninstalling that and removing references from it.

Tmassery avatar Mar 07 '17 19:03 Tmassery

~@ryanhomer @Tmassery This was happening to me too, also on a React Native project. I didn't want to track down the source of babel-plugin-jest-hoist because it's not something I installed directly - it's a dependency of another package.~

~But, looking at https://github.com/varmais/react-native-unit-tests/blob/master/.babelrc#L6, I decided to add~

  "env": {
    "mocha": {
      "plugins": [
        "rewire"
      ]
    }
  }

~to my babelrc and it worked!~

Oops nevermind, that was crazy talk. I can only get it to work by editing my local version of babel-plugin-jest-hoist 😢

sarahatwork avatar May 30 '17 02:05 sarahatwork

Is it incompatible with jest-hoist? I get a Invalid variable access: _extends whenever I use rewire babel plugin.

Apidcloud avatar Jun 08 '17 12:06 Apidcloud

I'm having the same issue like @ryanhomer. I'm working on a react-native app and I'm writing my unit-tests with jest.

When adding babel-plugin-rewire to my .babelrc-file I'm always getting the following issue:

Test suite failed to run

***/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: _get__

ElinaSchaefer77 avatar Jul 10 '17 11:07 ElinaSchaefer77

Issue is still happening :(

apolishch avatar Aug 27 '17 15:08 apolishch

same error in react native project.

app/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: get_

ghost avatar Sep 11 '17 08:09 ghost

Try out this solution: https://github.com/speedskater/babel-plugin-rewire/issues/109#issuecomment-200867686.

I was able to get past the invalid variable access issue by switching from import * syntax to explicit imports.

Explicit imports seem like a better idea to me anyways :)

jvivs avatar Sep 25 '17 22:09 jvivs

If anyone else is still having this problem: I incorporated @sarahatwork's local edit into an npm pretest:

"pretest": "sed -e 's/:__/:_/' -i node_modules/babel-plugin-jest-hoist/build/index.js"

That way it still works even if babel-plugin-jest-hoist gets reinstalled. Even with that, I also needed to follow some of the advice in the solution referenced by @jvivs and make sure there was a reference in my module to anything in it I wanted to test.

jjd314 avatar Nov 09 '17 11:11 jjd314

same error here with react native.

rsallar avatar Sep 15 '19 20:09 rsallar

@ryanhomer I was able to reproduce your error about _get__ with a single underscore before 'get'; The error occurs when you define a module and you try to test a function that is not exported and it is not used by a function that is exported.

This example should work:

file.js:

export default function bar() {
 ...
 foo();
 ...
}

function foo() {
  ...
}

file.tests.js:

const foo = require("./file").__get__("foo"); // it works

apierr avatar Apr 14 '20 13:04 apierr

A solution for TypeScript is here: https://stackoverflow.com/questions/54697062/test-or-mock-a-not-exported-function-with-jest-using-typescript.

FSou1 avatar Apr 22 '20 05:04 FSou1

Is there any solution to how can we mock Function without exporting and passing the test data for that to complete our test code? Also, can you guys help me how to pass data to the useState for the test code?

brijesh-imemori avatar Dec 18 '23 10:12 brijesh-imemori