Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Testing using jest broken since 0.14.0 #3999

Closed
gethinwebster opened this issue Nov 9, 2015 · 41 comments
Closed

Testing using jest broken since 0.14.0 #3999

gethinwebster opened this issue Nov 9, 2015 · 41 comments
Assignees
Labels
Resolution: Locked This issue was locked by the bot.

Comments

@gethinwebster
Copy link

The jestSupport/scriptPreprocess.js file that is recommended for use in testing (see https://facebook.github.io/react-native/docs/testing.html#jest-tests) was removed in 0.14.0:

54b1402

Using preprocessor.js instead doesn't work, because it makes assumptions about the folder structure, and therefore where babel-core/package.json can be found.

Can scriptPreprocess be added back in, or is there now a different recommendation for running tests?

@ashleydw
Copy link

I had the same problem. I solved it by removing babel-core from my package.json file (which I had in my file because I am using the hot loader [https://github.com/mjohnston/react-native-webpack-server]).

Once removed, babel-core will be installed into the react-native directory instead of the root node_modules.

@admmasters
Copy link
Contributor

Hmm having done that I'm getting: "babel.Transformer is not a function". Oh - this I think is related to master though and babel 6 specifically.

@tadeuzagallo
Copy link
Contributor

@admmasters Do you have any babel-plugin version 5 installed?

@MicheleBertoli
Copy link

I basically created a new react-native project, installed jest and get the following error (running Jest):
Error: ENOENT: no such file or directory, open '/Users/.../node_modules/react-native/node_modules/babel-core/package.json'

Setup:
Mac OS v10.10.5
node v5.0.0
npm v3.4.0
react-native-cli v0.1.7
react-native v0.14.2
jest-cli v0.7.1

Config:

"jest": {
  "scriptPreprocessor": "node_modules/react-native/jestSupport/preprocessor.js",
  "setupEnvScriptFile": "node_modules/react-native/jestSupport/env.js",
  "testPathIgnorePatterns": [
    "/node_modules/",
    "packager/react-packager/src/Activity/"
  ],
  "testFileExtensions": [
    "js"
  ],
  "unmockedModulePathPatterns": [
    "promise",
    "source-map"
  ]
},

/cc @cpojer

@dshalom
Copy link

dshalom commented Nov 25, 2015

Im having the same issue too, my settings are:
Mac OS v10.10.5
node v5.1
npm v3.5.0
react-native 0.15.0
jest-cli v0.8.0

@adrienthiery
Copy link
Contributor

As a quick-fix, if you have babel-core in your node_modules/ folder, you can symlink your node_modules folder into node_modules/react-native/ (ln -s pwd/node_modules/ ./node_modules/react-native/ from your root folder)

I guess the problem comes from here : https://github.com/facebook/react-native/blob/master/jestSupport/preprocessor.js#L29
If your project also has babel as a dependency, then react-native doesn't need to readd it, so it will be located in node_modules/ instead of being in the react-native folder.

@ahanriat
Copy link
Contributor

ahanriat commented Dec 4, 2015

This issue comes with npm 3.x as it try to flatten dependencies (see this article). You can resolve it by using the v4.2.3 of nodejs (I've done this for my CI).

@ahanriat
Copy link
Contributor

ahanriat commented Dec 4, 2015

@ide I think you can close this issue 🎉

@masom
Copy link

masom commented Dec 8, 2015

@ahanriat RN engine specs says anything greater than 4. https://github.com/facebook/react-native/blob/master/package.json#L11

Installing or upgrading node on OS X results in a borked jest.

@ide
Copy link
Contributor

ide commented Dec 8, 2015

Have people been able to get their own tests working with jest? Happy to close this but would like to point people at a blog post or similar resource if there's one available.

@masom
Copy link

masom commented Dec 8, 2015

@ide I got Jest running on 0.16.

NPM 2.x has to be installed. Won't work on vanilla NodeJS 5.x.

The docs only recommend using 2.x:

If you are using Node 5.0 or newer, we recommend installing npm 2, which is much faster than npm 3. After installing Node, run npm install -g npm@2.

http://facebook.github.io/react-native/docs/getting-started.html

Babel also does not seem to be transforming properly.

Doing require('../Something') does not return the default export.

@gethinwebster
Copy link
Author

@ide same here, managed to get it working by going back to NPM 2.x

@masom I believe that's due to the change to Babel 6 in 0.16: it used to return the default export as both require(module).default and plain require(module), but now the first method is needed: http://stackoverflow.com/questions/33505992/babel-6-changes-how-it-exports-default

@masom
Copy link

masom commented Dec 8, 2015

@gethinwebster In the app itself doing:

import Something from './Something';

works but when executing with Jest something screws up the transform and this happens:

  - TypeError: _Something2.default is not a function
        at Spec.<anonymous> (App/Models/__tests__/User-test.js:10:14)

@gethinwebster
Copy link
Author

Odd - pretty much the opposite behaviour to the related issue I saw! Probably worth opening a new issue for that, as it sounds like it's related to Babel 6 in 0.16, rather than the earlier changes to preprocessor.

@cpojer
Copy link
Contributor

cpojer commented Dec 8, 2015

Yeah there are a bunch of new technologies that got shipped pretty quickly and we didn't have enough time to figure all of this out in jest. We'll add better npm3 mocking support to jest "soon" and fix the issue with babel's imports.

@ahanriat
Copy link
Contributor

ahanriat commented Dec 9, 2015

@masom Totally agree, as long as node 5.x is packaged by default with npm 3, there is a breaking change in the way node modules are arranged. At this point there are two solution:

  • specify min required node version to 5.x and modify this the preprocessor script to match npm 3 requirements
  • specifify node version >= 4.x and < 5.x and let the preprocessor script as it is

@Andrewpk
Copy link

@ahanriat 👍

@pietropizzi
Copy link

@masom I have the exact same thing as you in RN 0.16: #4784

@pietropizzi
Copy link

@cpojer I think I narrowed it down to a bug in this babel plugin https://github.com/facebook/fbjs/blob/master/scripts/babel-6/inline-requires.js

If you set inlineRequires to false in https://github.com/facebook/react-native/blob/master/jestSupport/preprocessor.js#L23 it works. Meaning that something in the aforementioned plugin must be what is causing it.

@cpojer
Copy link
Contributor

cpojer commented Dec 15, 2015

The above issue about export default is unrelated to inline-requires. We are currently building a plugin to fix this but any help would be appreciated (we need someone to write a babel plugin :) ). The inline-require transform shouldn't be related to the export default issue. However, it might be an issue for your existing code.

We transform require statements (not imports) to be inline, which might break some of your tests and you have to fix them up manually. We've been using this transform for a long time though, did this just now get shipped with react-native?

@pietropizzi
Copy link

@cpojer The script I mentioned is quite new. It's first commit is on the 7th of November. It is the babel-6 version of the script, which has some slight differences from the babel-5 one.

I am using requires in my tests since there is an issue with import where the imported modules get hoisted to the to of the file and thereby get required before jest.dontMock calls.

It might still be that somehow our test-code is not handling the inline-requires too well. Not sure.

@cpojer
Copy link
Contributor

cpojer commented Dec 16, 2015

babel 6 changed how modules are imported. If you are using require for something that is exported using export default, for now you'll have to do require('Foo').default in your test. I realize this sucks and I'd like to fix this using a custom transform for test-files only that doesn't hoist imports. This should solve all of our problems regarding imports.

@pietropizzi
Copy link

@cpojer that would be great! I'm already using the require('Foo').default in my tests. But inside those modules that are being required something goes wrong.

@cpojer
Copy link
Contributor

cpojer commented Dec 16, 2015

Can you share a module that isn't working for you?

@akshaysmurthy
Copy link

I am on RN v0.17, node v5.1.0 and npm v2.14.15. I still get Error: ENOENT: no such file or directory, open '/Users/.../node_modules/react-native/node_modules/babel-core/package.json'

@ahanriat
Copy link
Contributor

@akshaysmurthy you should try with node 4.x.x (packaged with npm 2), this way you won't have this problem :)

ghost pushed a commit that referenced this issue Jan 18, 2016
Summary:
Related to #3999

There is an issue with the `preprocessor` script when using node >=5 as it uses npm 3. ~~There are (at least) two solutions, (I'm submitting the first one):~~
- ~~specify min required node version to 5.x and modify [this the preprocessor script](https://github.com/facebook/react-native/blob/0.16-stable/jestSupport/preprocessor.js#L29) to match npm 3 requirements~~
- ~~specifify node version >= 4.x and < 5.x and let the preprocessor script as it is~~

**EDIT**:
Using `require.resolve` will do the trick !

--
Thank you guys for this amazing project by the way ;)
Closes #4903

Reviewed By: svcscm

Differential Revision: D2838759

Pulled By: androidtrunkagent

fb-gh-sync-id: ebb12f225a519ea23afc4f013bb063a920193719
@john916zhang
Copy link

@akshaysmurthy I overcome this issue by modifying ./node_modules/react-native/jestSupport/preprocessor.js.

a370641

@akshaysmurthy
Copy link

@ahanriat I got @Anderson916's solution working, thanks!

@ahanriat
Copy link
Contributor

\o/

christopherdro pushed a commit to wildlifela/react-native that referenced this issue Jan 20, 2016
Summary:
Related to facebook#3999

There is an issue with the `preprocessor` script when using node >=5 as it uses npm 3. ~~There are (at least) two solutions, (I'm submitting the first one):~~
- ~~specify min required node version to 5.x and modify [this the preprocessor script](https://github.com/facebook/react-native/blob/0.16-stable/jestSupport/preprocessor.js#L29) to match npm 3 requirements~~
- ~~specifify node version >= 4.x and < 5.x and let the preprocessor script as it is~~

**EDIT**:
Using `require.resolve` will do the trick !

--
Thank you guys for this amazing project by the way ;)
Closes facebook#4903

Reviewed By: svcscm

Differential Revision: D2838759

Pulled By: androidtrunkagent

fb-gh-sync-id: ebb12f225a519ea23afc4f013bb063a920193719
MattFoley pushed a commit to skillz/react-native that referenced this issue Jan 21, 2016
Summary:
Related to facebook#3999

There is an issue with the `preprocessor` script when using node >=5 as it uses npm 3. ~~There are (at least) two solutions, (I'm submitting the first one):~~
- ~~specify min required node version to 5.x and modify [this the preprocessor script](https://github.com/facebook/react-native/blob/0.16-stable/jestSupport/preprocessor.js#L29) to match npm 3 requirements~~
- ~~specifify node version >= 4.x and < 5.x and let the preprocessor script as it is~~

**EDIT**:
Using `require.resolve` will do the trick !

--
Thank you guys for this amazing project by the way ;)
Closes facebook#4903

Reviewed By: svcscm

Differential Revision: D2838759

Pulled By: androidtrunkagent

fb-gh-sync-id: ebb12f225a519ea23afc4f013bb063a920193719
@ColCh
Copy link
Contributor

ColCh commented Feb 22, 2016

I have same issue , on React Native v0.19.0:

Error is thrown:

ReferenceError: _redux is not defined

For this source:

import {combineReducers} from 'redux';
export default combineReducers({
  time: (state = 0, action = {}) => {
    switch (action.type) {
      case SET_TIME:
        return action.time;
      case APPEND_TIME:
        return state + action.time;
      default:
        return state;
    }
  },
});

It gets transpiled to:

Object.defineProperty(exports,"__esModule",{value:true});exports.default=
(0,_redux.combineReducers)({
time:function(){var state=arguments.length<=0||arguments[0]===undefined?0:arguments[0];var action=arguments.length<=1||arguments[1]===undefined?{}:arguments[1];
switch(action.type){
case SET_TIME:
return action.time;
case APPEND_TIME:
return state+action.time;
default:
return state;}}});

(_redux.combineReducers, but no _redux defined)

But if I change inlineRequires to false, script gets transpilled right:

Object.defineProperty(exports,"__esModule",{value:true});var _redux=require('redux');exports.default=
(0,_redux.combineReducers)({
time:function(){var state=arguments.length<=0||arguments[0]===undefined?0:arguments[0];var action=arguments.length<=1||arguments[1]===undefined?{}:arguments[1];
switch(action.type){
case SET_TIME:
return action.time;
case APPEND_TIME:
return state+action.time;
default:
return state;}}});

(See that var _redux=require('redux'); ?)

UPD: same for RN 0.21.0-rc and 0.20.0 as well...

@cpojer
Copy link
Contributor

cpojer commented Feb 23, 2016

The latest version of babel6 should have a way to add a separate transform pass, see: https://github.com/babel/babel/blob/master/CHANGELOG.md#a-traversal-per-preset-experimental

can you try putting the inline require transform into a separate pass, after all the others and show he output?

I'm currently working on fixing imports for jest 0.9 as well and hope this problem will go away.

@ColCh
Copy link
Contributor

ColCh commented Feb 23, 2016

Patched react-native/packager/transformer.js:

  //if (options.inlineRequires) {
  //  extraPlugins.push(inlineRequires);
  //}
  config.plugins = resolvePlugins(extraPlugins.concat(config.plugins));


  var babelConfig = Object.assign({}, babelRC, config);

  babelConfig.passPerPreset = true;
  babelConfig.presets = [ {"plugins":babelConfig.plugins}, {"plugins":[inlineRequires]} ];
  delete babelConfig.plugins;

  const result = babel.transform(src, babelConfig);

Transpilled script, for same source as above:

Object.defineProperty(exports,"__esModule",{value:true});exports.default=

(0,require('redux').combineReducers)({
time:function(){var state=arguments.length<=0||arguments[0]===undefined?0:arguments[0];var action=arguments.length<=1||arguments[1]===undefined?{}:arguments[1];
switch(action.type){
case SET_TIME:
return action.time;
case APPEND_TIME:
return state+action.time;
default:
return state;}}});

But then ...

TypeError: (0 , require(...).combineReducers) is not a function

wtf?! this may be unrelated to this issue

@cpojer
Copy link
Contributor

cpojer commented Feb 23, 2016

Just double checking, is redux in your unmockedModulePathPatterns list in your config?

@ColCh
Copy link
Contributor

ColCh commented Feb 23, 2016

No, I find other way to require it (for now):

jest.autoMockOff();
const TimerDuck = require(`../TimerDuck`);
jest.autoMockOn();

Should I check unmockedModulePathPatterns?

@cpojer
Copy link
Contributor

cpojer commented Feb 23, 2016

I'll recommend doing that instead of disabling/enabling auto-mocking.

[email protected] will be tagged soon as another beta for the new jest version. It will support proper transitive dependency unmocking for npm3, so that might also fix your issues. I'll tag it sometime this week :)

@ColCh
Copy link
Contributor

ColCh commented Feb 23, 2016

I'd like to use:

jest.dontMock(`redux`);
jest.dontMock(`../TimerDuck`);
const TimerDuck = require(`../TimerDuck`);

But it returns mocked version of redux on my source.

I see commit 7b44ca in Jest . Nice! Waiting for npm publish :)

And... what about inlineRequires?

@jsierles
Copy link
Contributor

@gethinwebster @ColCh is this issue still relevant? Let me know if we can close it in favor of a PR or more specific issue.

@grabbou
Copy link
Contributor

grabbou commented Mar 20, 2016

My tests still break because of some import statements in the code (but they used to work). Let me check that internally tomorrow and report back.

@cpojer
Copy link
Contributor

cpojer commented Mar 21, 2016

I'm currently rewriting the documentation around Jest. The latest version of Jest and babel-jest have this issue resolved, but the integration with react-native isn't ideal yet. There'll be more info soon :)

@cpojer cpojer self-assigned this Mar 21, 2016
@ColCh
Copy link
Contributor

ColCh commented Mar 23, 2016

@jsierles my case works for me now

@cpojer
Copy link
Contributor

cpojer commented Jul 27, 2016

Thank you for your patience. We launched Jest 14.0 with experimental react-native support:

Please feel free to create new issues after trying out the new integration if any issues remain.

@cpojer cpojer closed this as completed Jul 27, 2016
@facebook facebook locked as resolved and limited conversation to collaborators Jul 20, 2018
@react-native-bot react-native-bot added the Resolution: Locked This issue was locked by the bot. label Jul 20, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Resolution: Locked This issue was locked by the bot.
Projects
None yet
Development

No branches or pull requests