I followed the instructions to setup jest tests for react-native-mapbox-gl (adding '@react-native-mapbox-gl/maps/setup-jest' to setupFilesAfterEnv), but it destroys hundreds of tests written before.
I get SyntaxError: Unexpected token { on every test.
After adding mapbox-gl to transformIgnorePatterns in the jest config, half of the tests in the project are still failing with the exception Right-hand side of 'instanceof' is not an object.
When I flip the load order of the setupTests.js file and '@react-native-mapbox-gl/maps/setup-jest' I am getting errors Invariant Violation: Native module cannot be null regarding every test which targets components importing MapBoxGL.
It should not destroy my tests, nor break tests regarding the components importing MapboxGL when you do the jest setup shown in docs.
The package.json:
{
"name": "my-app",
"scripts": {
"start": "react-native start --reset-cache",
"test": "jest --verbose --collect-coverage",
"android": "react-native run-android",
},
"dependencies": {
"@react-native-community/async-storage": "^1.6.3",
"@react-native-community/checkbox": "^0.2.2",
"@react-native-community/geolocation": "^2.0.2",
"@react-native-community/masked-view": "^0.1.7",
"@react-native-community/netinfo": "^4.6.1",
"@react-native-community/picker": "^1.3.0",
"@react-native-mapbox-gl/maps": "^8.1.0-rc.2",
"@react-navigation/native": "^5.1.5",
"@react-navigation/stack": "^5.2.10",
"@redux-offline/redux-offline": "^2.5.2-native.1",
"@voximplant/react-native-foreground-service": "^2.0.0",
"i18next": "^19.0.0",
"moment-timezone": "^0.5.27",
"react": "16.11.0",
"react-dom": "16.9.0",
"react-i18next": "^11.2.2",
"react-native": "0.62.1",
"react-native-camera": "^3.26.0",
"react-native-gesture-handler": "^1.5.6",
"react-native-permissions": "^2.0.4",
"react-native-reanimated": "^1.2.0",
"react-native-safe-area-context": "^0.7.3",
"react-native-screens": "^2.7.0",
"react-native-svg": "^12.0.3",
"react-native-svg-transformer": "^0.14.3",
"react-native-vector-icons": "^6.6.0",
"react-native-version-check": "^3.4.0",
"react-redux": "^7.1.1",
"redux": "^4.0.4",
"redux-thunk": "^2.3.0"
},
"devDependencies": {
"@babel/core": "^7.9.0",
"@storybook/addon-actions": "^5.3.1",
"@storybook/addon-links": "^5.3.1",
"@storybook/addons": "^5.3.1",
"@storybook/react-native": "^5.3.1",
"@storybook/react-native-server": "^5.3.1",
"babel-eslint": "^10.0.3",
"babel-jest": "24.9.0",
"babel-loader": "^8.0.6",
"babel-preset-expo": "^7.1.0",
"detox": "^14.9.0",
"enzyme": "^3.10.0",
"enzyme-adapter-react-16": "^1.15.0",
"eslint": "^6.3.0",
"eslint-config-airbnb": "^18.0.1",
"eslint-plugin-import": "^2.18.2",
"eslint-plugin-jsx-a11y": "^6.2.3",
"eslint-plugin-react": "^7.14.3",
"eslint-plugin-react-hooks": "^2.2.0",
"jest": "^24.9.0",
"jest-enzyme": "^7.1.1",
"jest-fetch-mock": "^2.1.2",
"jetifier": "^1.6.4",
"jsdom": "^15.1.1",
"metro-react-native-babel-preset": "0.58.0",
"react-native-dotenv": "^0.2.0",
"react-test-renderer": "16.11.0",
"redux-logger": "^3.0.6",
"redux-mock-store": "^1.5.3"
},
"private": true,
"detox": {
"test-runner": "jest",
"configurations": {
"android.emu.debug": {
"binaryPath": "android/app/build/outputs/apk/debug/app-debug.apk",
"build": "cd android ; ./gradlew app:assembleDebug app:assembleAndroidTest -DtestBuildType=debug ; cd -",
"type": "android.emulator",
"device": {
"avdName": "smartphone"
}
},
"android.emu.release": {
"binaryPath": "android/app/build/outputs/apk/release/app-release.apk",
"build": "cd android ; ./gradlew app:assembleRelease -Pcleartext='true' app:assembleAndroidTest -Pcleartext='true' -DtestBuildType=release ; cd -",
"type": "android.emulator",
"device": {
"avdName": "smartphone"
}
}
}
}
}
The jest.config.js:
module.exports = {
preset: 'react-native',
testPathIgnorePatterns: [
'/node_modules/',
],
transformIgnorePatterns: [
'node_modules/(?!((jest-)?react-native|react-clone-referenced-element|moment|expo(nent)?|@expo(nent)?/.*|@react-navigation|react-navigation|react-native-gesture-handler|@react-native-mapbox-gl/maps|@react-native-community))',
],
automock: false,
setupFilesAfterEnv: [
'@react-native-mapbox-gl/maps/setup-jest',
'./setupTests.js',
],
};
The App was once an expo app that then got ejected. I do not know if this might cause any problems.
Or eventually there are known conflicts regarding my versions in package.json?
I just set this up a week or two ago and ran into the first issue until I added the transformIgnorePatterns bit. It sounds like maybe we need to update our docs to include that in the jest setup.
For the other issue, I don't remember seeing that particular error. Could you post an example of the code for a failing unit test and its setup? Maybe a stack trace so we can see exactly where it is failing?
I added this to a file in my __mocks__ folder as well, but I'm not sure if it will help fix your problem. You may have other parts of the code that you are using that you need to add to this as well, but even then I'm not sure that it will fix it for you:
export default {
MapView: 'MapView',
StyleURL: {
Street: 'Street',
Dark: 'Dark',
Light: 'Light',
Outdoors: 'Outdoors',
Satellite: 'Satellite',
SatelliteStreet: 'SatelliteStreet',
TrafficDay: 'TrafficDay',
TrafficNight: 'TrafficNight'
},
ShapeSource: 'ShapeSource',
SymbolLayer: 'SymbolLayer',
Camera: 'Camera'
};
hey @HughBoert, sorry for the late reply.
The invariant violation comes probably from Logger importing and using NativeEventEmitter.
I've set up a new react-native project and fiddled a bit with it.
I'm not sure what setupTests.js does, however do flip them around to cause the invariant violation issue and put this in node_modules/@react-native-mapbox-gl/maps/setup-jest.js:
jest.mock('react-native/Libraries/EventEmitter/NativeEventEmitter.js', () => {
function MockEventEmitter() {}
MockEventEmitter.prototype.addListener = jest.fn(() => ({remove: jest.fn()}));
MockEventEmitter.prototype.removeListener = jest.fn();
return MockEventEmitter;
});
let me know how that works out for you
Thanks 馃檱
I can verify that this happens on the latest version:
"@react-native-mapbox-gl/maps": "^8.1.0-rc.9"
Thanks for the comment @agabriele-radius.
Can you share your setup please?
Also, did you find a workaround?
This fails on an empty react-native init
Here's a sample repo I set up to prove this
There's a patch as per @ferdicus's comment above on the b/patches branch
This sample repo also fails build on ios as per https://github.com/react-native-mapbox-gl/maps/issues/1097
I have the same issue. It would be good to know if there's a solution in the horizon
jest.mock('react-native/Libraries/EventEmitter/NativeEventEmitter.js', () => { function MockEventEmitter() {} MockEventEmitter.prototype.addListener = jest.fn(() => ({remove: jest.fn()})); MockEventEmitter.prototype.removeListener = jest.fn(); return MockEventEmitter; });
This fixed the issue for me. Thanks for posting @ferdicus
PRs are welcome :)
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
Hi, everyone!
I'm experiencing the same issue when I try to run my tests.
I tried @ferdicus suggestion, but after modifying setup-jest.js I got this error:
TypeError: _reactNative.NativeEventEmitter is not a constructor
at Object.<anonymous> (node_modules/@react-native-mapbox-gl/maps/javascript/modules/location/locationManager.js:6:43)
at Object.<anonymous> (node_modules/@react-native-mapbox-gl/maps/javascript/components/UserLocation.js:4:1)
This is a fresh RN project where I added react-native-mapbox-g.
Edited: complete package.json
{
"name": "dollaridechallenge",
"version": "0.0.1",
"private": true,
"scripts": {
"android": "react-native run-android",
"ios": "react-native run-ios",
"start": "react-native start",
"test": "jest",
"lint": "eslint ."
},
"dependencies": {
"@react-native-mapbox-gl/maps": "^8.2.0-beta2",
"@reduxjs/toolkit": "^1.5.1",
"apisauce": "^2.1.1",
"react": "17.0.1",
"react-native": "0.64.0",
"react-native-vector-icons": "^8.1.0",
"react-redux": "^7.2.4",
"redux": "^4.1.0",
"redux-saga": "^1.1.3",
"reduxsauce": "^1.2.0",
"seamless-immutable": "^7.1.4"
},
"devDependencies": {
"@babel/core": "^7.12.9",
"@babel/runtime": "^7.12.5",
"@react-native-community/eslint-config": "^2.0.0",
"babel-jest": "^26.6.3",
"eslint": "7.14.0",
"jest": "^26.6.3",
"metro-react-native-babel-preset": "^0.64.0",
"react-test-renderer": "17.0.1"
}
}
@matias91, I believe this is still the same issue.
The underlying issue is NativeEventEmitter which is a react-native module.
If you do not mock it, jest will attempt to call it and be like 馃し馃徔 .
You have to mock it in order to run the tests properly.
Thanks for the answer, @ferdicus!
I'll try to mock it
Thanks for the answer, @ferdicus!
I'll try to mock it
Just to be clear, this:
jest.mock('react-native/Libraries/EventEmitter/NativeEventEmitter.js', () => {
function MockEventEmitter() {}
MockEventEmitter.prototype.addListener = jest.fn(() => ({remove: jest.fn()}));
MockEventEmitter.prototype.removeListener = jest.fn();
return MockEventEmitter;
});
is supposed to mock it
@ferdicus, sorry for my late answer.
I added that and it didn't mock it. I'll take a look later, maybe I did something wrong.
But I did added that to the setup-jest.js
@matias91 , @agabriele-radius , @ElZombieIsra
coming back to this I noticed, that it doesn't seem to work with newer RN setups anymore 馃槥
However, I was able to mock it successfully by adding an extra setup file for jest like this:
// jest-setup.js
jest.mock('react-native/Libraries/EventEmitter/NativeEventEmitter.js', () =>
require('react-native/Libraries/EventEmitter/__mocks__/NativeEventEmitter.js')
);
then simply add this to your jest config in package.json:
"setupFilesAfterEnv": [
"@react-native-mapbox-gl/maps/setup-jest",
"<rootDir>/jest-setup.js"
]
Can you try and let me know if that helps?
Thanks
Most helpful comment
I have the same issue. It would be good to know if there's a solution in the horizon