React Native Environment Info:
System:
OS: macOS High Sierra 10.13.6
CPU: x64 Intel(R) Core(TM) i5-7360U CPU @ 2.30GHz
Memory: 844.84 MB / 16.00 GB
Shell: 5.3 - /bin/zsh
Binaries:
Node: 8.11.3 - ~/.nvm/versions/node/v8.11.3/bin/node
Yarn: 1.7.0 - /usr/local/bin/yarn
npm: 5.6.0 - ~/.nvm/versions/node/v8.11.3/bin/npm
Watchman: 4.9.0 - /usr/local/bin/watchman
SDKs:
iOS SDK:
Platforms: iOS 11.4, macOS 10.13, tvOS 11.4, watchOS 4.3
Android SDK:
Build Tools: 23.0.1, 25.0.0, 25.0.1, 25.0.2, 25.0.3, 26.0.1, 26.0.2, 26.0.3, 27.0.3
API Levels: 23, 24, 25, 26, 27
IDEs:
Android Studio: 2.3 AI-162.4069837
Xcode: 9.4.1/9F2000 - /usr/bin/xcodebuild
npmPackages:
react: 16.4.1 => 16.4.1
react-native: 0.56.0 => 0.56.0
npmGlobalPackages:
react-native-cli: 2.0.1
Essentially – upon starting a brand new RN project (react-native init), running yarn test fails with the error:
Plugin 0 specified in "project/node_modules/babel-preset-react-native/index.js" provided an invalid property of "default" (While processing preset: "project/node_modules/babel-preset-react-native/index.js")
I'm not sure why this is – I think it's something to do with babel-preset-react-native@5. So that's the primary issue that needs fixing, and I think the RN team are already aware of it.
This issue has already been discussed in some detail in https://github.com/facebook/react-native/issues/19859 and an answer has been given in https://github.com/facebook/react-native/issues/19859#issuecomment-407748189 but I found that the solution given didn't seem to fix things for me, so I'm opening a new issue as that thread has been locked.
The thread linked above suggests adding this line to your Jest config to fix things:
"transform": {
"^.+\\.js$": "<rootDir>/node_modules/react-native/jest/preprocessor.js"
}
As I understand it, this means that babel-jest is bypassed, instead using an alternative that was originally intended to be used to run the test suite in the RN repo itself.
When I did this, I found that a good number of my tests started to pass, but all the tests I had that had calls to jest.mock were still failing. I did some further investigation and it became clear that jest.mock was not being hoisted above my import calls (and actually, even if I explicitly moved jest.mock calls above the imports, it still fails as imports themselves get hoisted above everything).
I'm not 100% sure why my jest.mock calls were not getting hoisted above imports. I have a theory: the RN repo itself is written using Haste rather than ES6 imports, so the RN preprocessor does not include babel-plugin-jest-hoist. Maybe that's wrong though. But either way, they definitely weren't getting hoisted.
So anyway, I deleted the preprocessor bit from my Jest config. Instead, I installed babel-core@^7.0.0-bridge.0 (as per the advice of some of the other answers in the repo). I'm not sure why this is necessary, but I found that that made my Jest tests pass correctly.
However, I then found that by adding babel-core as an explicit dependency of my project, RN 0.56 would crash while bundling (with the error Error: Cannot find module '@babel/parser'). So then I added @babel/core@^7.0.0-rc.1 and now both my app and my tests run correctly.
I'm aware this solution isn't very nice, as RN is supposed to take care of babel under the hood. However, it's the only way I've been able to upgrade to RN 0.56 and have Jest run correctly. So I thought it was worth flagging.
react-native init testprojectyarn test. You will see it fails with the error Plugin 0 specified in "project/node_modules/babel-preset-react-native/index.js" provided an invalid property of "default" (While processing preset: "project/node_modules/babel-preset-react-native/index.js")Can you run react-native info and edit your issue to include these results under the Environment section?
If you believe this information is irrelevant to the reported issue, you may write [skip envinfo] under Environment to let us know.
I did this – I'm not sure why the bot is complaining?
This is probably a duplicate of #19859 and that topic in general is under work. Did you check current master-branch is working for you?
Duplicate of #19859
Haha - I realise it's a duplicate of that issue (I linked it in my description), but that thread was locked with a workaround that didn't seem to work, so thought it was worth making a new issue to:
preprocessor workaround doesn't seem work as advertisedApologies if opening a duplicate issue wasn't the correct thing to do – my initial message should have made it a bit clearer.
@FibreFoX I haven't tried it against master, no.
Just as an update for anyone who found this useful:
Using react-native's custom preprocessor remains a non-workable solution for me on RN 0.57 (due to it not hoisting calls to jest.mock as I mentioned above.
After following the upgrade instructions I was able to get jest working by changing my .babelrc to babel.config.js. However, that then broke metro (it was complaining about regeneratorRuntime not being defined or something), so I couldn't build my actual app.
So I went back to using .babelrc to get my app to build, and I've written a custom Jest preprocessor that will manually load the .babelrc file, which seems to get around the issue of .babelrc being incorrectly automatically detected by babel-jest. This is what my new preprocessor looks like:
// jest-preprocessor.js
const fs = require("fs")
const config = fs.readFileSync("./.babelrc")
module.exports = require("babel-jest").createTransformer(JSON.parse(config))
And so to hook that up to Jest, I added this to my jest config:
"transform": {
"^.+\\.js$": "<rootDir>/jest-preprocessor.js"
}
Also, when you're messing around with preprocessors, make sure you run Jest with the --no-cache flag – credit here.
I finally resolved this issue by bringing in https://www.npmjs.com/package/babel-plugin-jest-hoist to my project.
My dependencies:
"react": "16.5.1",
"react-native": "^0.57.1",
..
"@babel/core": "^7.1.0",
"@babel/runtime": "^7.0.0",
"babel-core": "^6.26.3",
"babel-eslint": "^8.1.1",
"babel-jest": "^23.6.0",
"babel-plugin-jest-hoist": "^23.2.0",
"babel-plugin-relay": "^1.5.0",
"jest": "^23.6.0",
"metro-react-native-babel-preset": "^0.47.0",
and my babel.config.js:
module.exports = {
"presets": ["module:metro-react-native-babel-preset", "module:react-native-dotenv"],
"plugins": [
"relay",
"jest-hoist"
]
}
Most helpful comment
Just as an update for anyone who found this useful:
Using
react-native's custom preprocessor remains a non-workable solution for me on RN 0.57 (due to it not hoisting calls tojest.mockas I mentioned above.After following the upgrade instructions I was able to get jest working by changing my
.babelrctobabel.config.js. However, that then broke metro (it was complaining about regeneratorRuntime not being defined or something), so I couldn't build my actual app.So I went back to using
.babelrcto get my app to build, and I've written a custom Jest preprocessor that will manually load the.babelrcfile, which seems to get around the issue of.babelrcbeing incorrectly automatically detected bybabel-jest. This is what my new preprocessor looks like:And so to hook that up to Jest, I added this to my jest config:
Also, when you're messing around with preprocessors, make sure you run Jest with the
--no-cacheflag – credit here.