Jest: [react-native] Mock `findNodeHandle`

Created on 1 Jun 2017  路  11Comments  路  Source: facebook/jest

Had to choose between the react-native repo or this, but chose this one because the issue is more about how to mock some code rather that react-native specific details.


I鈥檓 running into an issue where findNodeHandle is getting invoked, which results in:

/Users/eloy/Code/Artsy/emission/node_modules/react-native/Libraries/Renderer/src/renderers/native/ReactNativeStack.js:44
return nodeHandle.getHostNode();
                  ^

TypeError: nodeHandle.getHostNode is not a function
    at Object.findNodeHandle (/Users/eloy/Code/Artsy/emission/node_modules/react-native/Libraries/Renderer/src/renderers/native/ReactNativeStack.js:44:19)
    at Component.focus (/Users/eloy/Code/Artsy/emission/node_modules/react-native/Libraries/Renderer/src/renderers/native/NativeMethodsMixin.js:145:43)
    at Component.<anonymous> (/Users/eloy/Code/Artsy/emission/node_modules/react-timer-mixin/TimerMixin.js:18:16)
    at ontimeout (timers.js:386:14)
    at tryOnTimeout (timers.js:250:5)
    at Timer.listOnTimeout (timers.js:214:5)

I tried to modify react-native鈥檚 mock setup to:

  .mock('TextInput', () => {
    const TextInput = mockComponent('TextInput');
    TextInput.prototype.focus = function() {
      console.log("Focus, yo!");
    }
    return TextInput;
  })

Because the autoFocus prop of the TextInput component leads to focus being invoked, which in turn is the one that tries to use findNodeHandle.

I鈥檓 wondering if my override isn鈥檛 working because the method is actually defined in a mixin? And/or if you have other tips? Like, I鈥檓 not sure if findNodeHandle should ever really be used in tests, if not I鈥檇 like to PR a change to the mocks in the react-native repo.

Most helpful comment

As an alternative workaround to referencing the test object within the app, I added the following code to a setup file to ignore the autoFocus prop during mock creation:

jest.mock('TextInput', () => {
  const RealComponent = require.requireActual('TextInput');
  const React = require('React');
  class TextInput extends React.Component {
    render() {
      delete this.props.autoFocus;
      return React.createElement('TextInput', this.props, this.props.children);
    }
  }
  TextInput.propTypes = RealComponent.propTypes;
  return TextInput;
});

All 11 comments

As an alternative workaround to referencing the test object within the app, I added the following code to a setup file to ignore the autoFocus prop during mock creation:

jest.mock('TextInput', () => {
  const RealComponent = require.requireActual('TextInput');
  const React = require('React');
  class TextInput extends React.Component {
    render() {
      delete this.props.autoFocus;
      return React.createElement('TextInput', this.props, this.props.children);
    }
  }
  TextInput.propTypes = RealComponent.propTypes;
  return TextInput;
});

@jpklein Oh yeah, that鈥檚 definitely a better workaround than mine 馃憤 Alas both workarounds suffer from the prop no longer showing up in Jest snapshots :/

This is definitely not a Jest issue, it's how Jest is being used. This issue tracker is not the place for help requests such as this.

I guess I should have been more clear in that the setup for RN is incomplete. So this isn鈥檛 a help request for my specific application, it鈥檚 more a help request for how to fix the incomplete RN setup.

That is also not appropriate to be discussed on the Jest issue tracker but rather the RN one.

Fair enough 馃憤

@jpklein Your code doesn't work any more after upgrading React-Native form 0.45.1 to 0.46.1 and caused by <SectionList/>.

Any new workaround?

@xareelee I was unable to replicate your issue with RN 0.46.2. Please take further discussion to facebook/react-native#14434

@jpklein I found the issue was caused by getScrollableNode in VirtualizedList. I do the same mock on VirtualizedList to solve this problem temporally.

See https://github.com/facebook/react-native/issues/15000#issuecomment-315221218 for more info.

Hello, I'm still having this problem even with no autoFocus and autoCorrect in RN 0.48.4 and jest-expo 21.0.2,
thanks

I had to modify the workaround slightly for RN 0.56:

jest.mock('TextInput', () => {
  const RealComponent = require.requireActual('TextInput');
  const React = require('React');

  class TextInput extends React.Component {
    render() {
      return React.createElement('TextInput', {...this.props, autoFocus: false}, this.props.children);
    }
  }
  TextInput.propTypes = RealComponent.propTypes;
  return TextInput;
});
Was this page helpful?
0 / 5 - 0 ratings