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

Jest React Native - Invariant Violation: Native module cannot be null. #2208

Closed
MechanicKim opened this Issue Dec 2, 2016 · 23 comments

Comments

Projects
None yet
@MechanicKim

MechanicKim commented Dec 2, 2016

Do you want to request a feature or report a bug?
bug

What is the current behavior?
When I run 'npm run jest', I got an error like this.
Invariant Violation: Native module cannot be null.

  at invariant (node_modules/fbjs/lib/invariant.js:38:15)
  at Linking.NativeEventEmitter (node_modules/react-native/Libraries/EventEmitter/NativeEventEmitter.js:32:1)
  at new Linking (node_modules/react-native/Libraries/Linking/Linking.js:119:141)
  at Object.<anonymous> (node_modules/react-native/Libraries/Linking/Linking.js:191:16)
  at Object.get Linking [as Linking] (node_modules/react-native/Libraries/react-native/react-native.js:91:22)
  at Object.<anonymous> (node_modules/react-native-experimental-navigation/NavigationRootContainer.js:15:36)

If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal repository on GitHub that we can npm install and npm test.

  1. cd react-native-router-flux
  2. npm install
  3. cd Example
  4. npm install
  5. npm run jest

https://github.com/MechanicKim/react-native-router-flux

What is the expected behavior?
Pass the jest test and update snapshot

Run Jest again with --debug and provide the full configuration it prints. Please mention your node and npm version and operating system.
Darwin 16.1.0
node v7.2.0
npm v3.10.9

@cpojer

This comment has been minimized.

Contributor

cpojer commented Dec 2, 2016

Set the preset to "react-native" and remove jest-react-native. It isn't needed any more with 0.38!

@cpojer cpojer closed this Dec 2, 2016

@MechanicKim

This comment has been minimized.

MechanicKim commented Dec 2, 2016

@cliedeman

This comment has been minimized.

cliedeman commented Dec 4, 2016

I am also getting this error.

Steps to reproduce:

  • react-native init a fresh project with 0.39
  • run jest, tests pass
  • Add dependency "react-native-router-flux": "^3.37.0"
  • Add import import { Router, Scene } from 'react-native-router-flux'
  • run jest, get the above error

The current jest setup.js does not mock out Linking.

I was able to get past the error by adding

Linking: {
  addEventListener: jest.fn(),
  removeEventListener: jest.fn(),
  openURL: jest.fn(),
  canOpenURL: jest.fn(),
  getInitialURL: jest.fn(),
},

After AsyncLocalStorage {...},

The problematic line is const Linking = require('react-native').Linking; from the react-native-experimental-navigation fork that react-native-router-flux uses.

package.json:

{
	"name": "test",
	"version": "0.0.1",
	"private": true,
	"scripts": {
		"start": "node node_modules/react-native/local-cli/cli.js start",
		"test": "jest"
	},
	"dependencies": {
		"react": "15.4.1",
		"react-native": "^0.39.0",
		"react-native-router-flux": "^3.37.0"
	},
	"jest": {
		"preset": "react-native"
	},
	"devDependencies": {
		"babel-jest": "17.0.2",
		"babel-preset-react-native": "1.9.0",
		"jest": "17.0.3",
		"react-test-renderer": "15.4.1"
	}
}

@cpojer Is there any way to mock out react native Linking globally without duplicating the setup.js file?

@cliedeman

This comment has been minimized.

cliedeman commented Dec 4, 2016

Figured it out

Created a file jest/setup.js with the following content

jest.mock('Linking', () => {
  return {
    addEventListener: jest.fn(),
    removeEventListener: jest.fn(),
    openURL: jest.fn(),
    canOpenURL: jest.fn(),
    getInitialURL: jest.fn(),
  }
})

Add changed my package.json

...
"jest": {
	"preset": "react-native",
	"setupFiles": ["jest/setup.js"]
},
...

Although there has been some change behaviour because previously this mock was not required.

@rewieer

This comment has been minimized.

rewieer commented Dec 6, 2016

I've got this problem as well on RN 38 with Jest 17.0.3. The problem is coming from NetInfo and react-native-router-flux. This is how i Implemented this from your solution :

jest.mock('Linking', () => {
  return {
    addEventListener: jest.fn(),
    removeEventListener: jest.fn(),
    openURL: jest.fn(),
    canOpenURL: jest.fn(),
    getInitialURL: jest.fn(),
  }
});

jest.mock('NetInfo', () => {
  return {
    isConnected: {
      fetch: () => {
        return new Promise((accept, resolve) => {
          accept(true);
        })
      }
    }
  }
});
@cwahlfeldt

This comment has been minimized.

cwahlfeldt commented Dec 9, 2016

@cliedeman Worked me for me thanks! However I feel like RN or Jest needs to figure it out. :)

@rewieer

This comment has been minimized.

rewieer commented Dec 10, 2016

I think it's more the job of the react-native preset to figure it out, rather than jest itself

@cpojer

This comment has been minimized.

Contributor

cpojer commented Dec 10, 2016

We merged this preset back into react-native; please send mocks and PRs directly there.

@rewieer

This comment has been minimized.

rewieer commented Dec 10, 2016

I'll give it a shot when i'll have some time.

@hybrisCole

This comment has been minimized.

hybrisCole commented Dec 23, 2016

the same thing happened to me, had to

jest.mock('PushNotificationIOS', () => ({
  addEventListener: jest.fn(),
  requestPermissions: jest.fn(),
}));
@gpminsuk

This comment has been minimized.

gpminsuk commented Dec 31, 2016

Cleaner solution using __mocks__
Create __mocks__ directory next to __tests__ and place react-native.js with

const rn = require('react-native')
jest.mock('Linking', () => {
  return {
    addEventListener: jest.fn(),
    removeEventListener: jest.fn(),
    openURL: jest.fn(),
    canOpenURL: jest.fn(),
    getInitialURL: jest.fn(),
  }
})
module.exports = rn
@JeroenNelen

This comment has been minimized.

JeroenNelen commented Jan 2, 2017

Edited; I had to refer to the file via "./jest/setup.js" since updating, before the "jest/setup.js" was working without any issues (I found the solution here: facebook/react-native#11585)


Any update on this? I was using this workaround:
"jest": { "preset": "react-native", "setupFiles": [ "jest/setup.js" ], "collectCoverage": true, "verbose": true },

But since updating all my packages to the latest versions today, Jest keeps giving this error:
Error: Jest: Module "jest/setup.js" in the "setupFiles" option was not found.

Any clue why it can no longer find the file? It hasn't moved or anything.

Kind regards,

@tijs tijs referenced this issue Jan 5, 2017

Closed

Update Homepage #2365

0 of 6 tasks complete
@alexxv

This comment has been minimized.

alexxv commented Jan 8, 2017

@JeroenNelen I've managed to workaround this with prepending <rootDir>:

"jest": {
    "preset": "jest-react-native",
    "setupFiles": [
      "<rootDir>/jest-setup.js"
    ]
  }```

Ugly, but works.
@cpojer

This comment has been minimized.

Contributor

cpojer commented Jan 8, 2017

In Jest 18.1, doing ./jest-setup.js will be resolved from the location of package.json.

@rewieer

This comment has been minimized.

rewieer commented Jan 9, 2017

Should there be a solution to mock custom components directly in jest ? A flow-typed like repository for example.

@cpojer

This comment has been minimized.

Contributor

cpojer commented Jan 9, 2017

That might be cool!

@andrewhl

This comment has been minimized.

andrewhl commented Mar 14, 2017

I have a similar issue. I have a saga that is importing:

import Camera from 'react-native-camera';

This throws the error:

 FAIL  js/sagas/App/__tests__/watchCheckDevicePermissions-test.js
  ● Test suite failed to run

    TypeError: Cannot read property 'Aspect' of undefined

      at Object.<anonymous> (node_modules/react-native-camera/index.js:254:78)
      at Object.<anonymous> (js/sagas/App/watchCheckDevicePermissions.js:26:95)
      at Object.<anonymous> (js/sagas/App/__tests__/watchCheckDevicePermissions-test.js:2:34)

I tried to define a Camera mock in ./js/jest/setup.js:

jest.mock('Camera', () => {
    return {
        Aspect: {}
    }
});

Which is required in package.json setupFiles. All my tests start throwing the error:

Cannot find module 'Camera' from 'setup.js'

I also get the Invariant error for other libraries. For example, Pusher. I get the Cannot find module warning if I try to mock Pusher:

jest.mock('Pusher', () => {
    return {
        addEventListener: jest.fn(),
        removeEventListener: jest.fn()
    }
});

This is my jest config in package.json:

  "jest": {
    "preset": "react-native",
    "setupFiles": ["./js/jest/setup.js"],
    "transformIgnorePatterns": [
      "node_modules/(?!react-native||@shoutem)"
    ]
  },

React version: 15.4.2
React-native version: ^0.40.0
Jest version: ^19.0.0

@andrewhl

This comment has been minimized.

andrewhl commented Mar 15, 2017

I got it working, but had to add the following to my jest/setup.js file (to get my saga tests running):

jest.mock('PushNotificationIOS', () => ({
    addEventListener: jest.fn(),
    requestPermissions: jest.fn(),
}));
jest.mock('react-native', () => ({
    NetInfo: {
        addEventListener: jest.fn(),
        fetch: () => {
            return {
                done: jest.fn()
            }
        }
    },
    NativeModules: {
        RNPasscodeStatus: {
            supported: jest.fn(),
            status: jest.fn(),
            get: jest.fn()
        }
    },
    Dimensions: {
        get: () => ({
            width: jest.fn(),
            height: jest.fn()
        })
    },
}));
jest.mock('react-native-camera', () => {
});

Is this overkill? Also, I need to explicitly call jest.unmock('react-native') in my component tests.

@morungos

This comment has been minimized.

morungos commented Mar 22, 2017

Hmmm, I've had to amend these slightly. I'm using react-native-push-notification version 2.2.1.

jest.mock('PushNotificationIOS', () => {
  return {
    addEventListener: jest.fn(),
    requestPermissions: jest.fn(() => Promise.resolve()),
    getInitialNotification: jest.fn(() => Promise.resolve()),
  }
});

Because requestPermissions and getInitialNotification seem to return a promise now. Would love this to be stable.

corymayer added a commit to corymayer/react-native-router-flux that referenced this issue May 12, 2017

corymayer added a commit to corymayer/react-native-router-flux that referenced this issue May 14, 2017

@DZuz14

This comment has been minimized.

DZuz14 commented May 28, 2017

For anyone having issues with react-native-router-flux, I had this problem today, and went with this solution #2208 (comment)

Quick and painless.

@kyangy

This comment has been minimized.

kyangy commented Jun 6, 2017

@andrewhl Were you able to successfully mock pusher? Im having trouble getting my tests fixed because of the Invariant Violation: Native module cannot be null. error

@andrewhl

This comment has been minimized.

andrewhl commented Jun 6, 2017

@kyangy I think in the end I didn't need to. The library that was causing problems was react-native-push-notification, which I mocked as follows:

jest.mock('react-native-push-notification', () => {
    return {
        addEventListener: jest.fn(),
        removeEventListener: jest.fn(),
        requestPermissions: jest.fn(),
        configure: jest.fn()
    }
});

Have you tried creating a jest/__mocks__/pusher.js file that looks something like:

module.exports = {
    // whatever methods or properties are being accessed via the pusher object
}

I was able to narrow down exactly what libraries and methods needed to be mocked by systematically removing all imports from the component/file under test, and commenting out a lot of code, and reintroducing things one at a time. I mocked whatever caused the test to squawk.

@mierz00

This comment has been minimized.

mierz00 commented May 8, 2018

Has any one had the same issue with react-native-callkit ?

 Invariant Violation: Native module cannot be null.

      635 | }
      636 |
    > 637 | export default function app(state = initialState, action) {
      638 |   switch (action.type) {
      639 |     case INIT:
      640 |       return {

      at invariant (node_modules/fbjs/lib/invariant.js:42:15)
      at new NativeEventEmitter (node_modules/react-native/Libraries/EventEmitter/NativeEventEmitter.js:37:1)
      at Object.<anonymous> (node_modules/react-native-callkit/index.js:10:23)

I've tried the solutions above but I gather I'm not mocking the right functions. Does any one have any ideas on what exactly should be mocked?

etoledom added a commit to wordpress-mobile/gutenberg-mobile that referenced this issue Oct 29, 2018

daniloercoli added a commit to wordpress-mobile/gutenberg-mobile that referenced this issue Nov 1, 2018

Merge branch 'master' of https://github.com/wordpress-mobile/gutenber…
…g-mobile into issue/167-merge-refresh-android

* 'master' of https://github.com/wordpress-mobile/gutenberg-mobile: (35 commits)
  Point to latest from RecyclerViewList
  Point to latest react-native-aztec
  Adding yarn.lock field for `turbo-combine-reducers`.
  Added turbo-combine-reducers dependency to fix failed builds
  Update subrepo ref to point to master again
  Update subrepo ref
  No need for change of default Jest platform
  Update subrepo ref
  Update subrepo ref to point to master again
  Update subrepo ref
  Update subrepo ref
  Update subrepo ref
  Update subrepo ref
  Add symlink in symlinked-packages-in-parent for notices
  Add symlink for notices package to fix the failing CI tests
  Update subrepo by merging from master
  Add support for nextpage block
  Fix lint warnings
  Mocking `react-native-gutenberg-bridge` to make iOS tests pass. From: facebook/jest#2208 (comment)
  rn-gutenberg-bridge: Adding dumb iOS implementation to avoid errors.
  ...

daniloercoli added a commit to wordpress-mobile/gutenberg-mobile that referenced this issue Nov 1, 2018

Merge branch 'master' of https://github.com/wordpress-mobile/gutenber…
…g-mobile into issue/167-merge-blocks-different-types

* 'master' of https://github.com/wordpress-mobile/gutenberg-mobile: (27 commits)
  Point to latest from RecyclerViewList
  Point to latest react-native-aztec
  Adding yarn.lock field for `turbo-combine-reducers`.
  Added turbo-combine-reducers dependency to fix failed builds
  Update subrepo ref to point to master again
  Update subrepo ref
  No need for change of default Jest platform
  Update subrepo ref
  Update subrepo ref
  Fix lint warnings
  Mocking `react-native-gutenberg-bridge` to make iOS tests pass. From: facebook/jest#2208 (comment)
  rn-gutenberg-bridge: Adding dumb iOS implementation to avoid errors.
  Revert "Update gutenberg subproject ref"
  Add react-native-hr library to add styled line+text elements easily
  Update gutenberg subproject ref
  Match wpandroid's Android API levels
  Remove plugin from Babel to make wpandroid release build work
  Fix wpandroid checkstyle issues
  Remove dep, Matro will find the package automagically
  Fix indentation
  ...

# Conflicts:
#	gutenberg

daniloercoli added a commit to wordpress-mobile/gutenberg-mobile that referenced this issue Nov 1, 2018

Merge branch 'master' of https://github.com/wordpress-mobile/gutenber…
…g-mobile into port-quote-block-step-1

* 'master' of https://github.com/wordpress-mobile/gutenberg-mobile: (27 commits)
  Point to latest from RecyclerViewList
  Point to latest react-native-aztec
  Adding yarn.lock field for `turbo-combine-reducers`.
  Added turbo-combine-reducers dependency to fix failed builds
  Update subrepo ref to point to master again
  Update subrepo ref
  No need for change of default Jest platform
  Update subrepo ref
  Update subrepo ref
  Fix lint warnings
  Mocking `react-native-gutenberg-bridge` to make iOS tests pass. From: facebook/jest#2208 (comment)
  rn-gutenberg-bridge: Adding dumb iOS implementation to avoid errors.
  Revert "Update gutenberg subproject ref"
  Add react-native-hr library to add styled line+text elements easily
  Update gutenberg subproject ref
  Match wpandroid's Android API levels
  Remove plugin from Babel to make wpandroid release build work
  Fix wpandroid checkstyle issues
  Remove dep, Matro will find the package automagically
  Fix indentation
  ...

# Conflicts:
#	gutenberg
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment