Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to simulate an event on a unit test with Jest, Enzyme for React-Native

I'm trying to figure out how to test an "onPress" event with Jest in a React-Native app so I can make sure the right function is called.

I went through the documentation and Google but couldn't find a solution for it in React-Native.

This is what I found that is supposed to work for React-Native with enzyme:

const mockFunc = jest.fn();
const component = mount(<MyComponent onPress={mockFunc} />);
component.simulate('press');
expect(mockFunc).toHaveBeenCalled();

But this doesn't work. Seems like mount doesn't work and I get this output:

ReferenceError: document is not defined

I tried with shallow instead but the TouchableOpacity is not getting rendered when I look at the output of the function... and you've guessed it, it doesn't work either. Not sure what to do.

Does anyone found a way to test events on React-Native?

Thanks

like image 765
alexmngn Avatar asked Feb 16 '17 07:02

alexmngn


People also ask

Can you use Enzyme for react native?

As of v0. 18, React Native uses React as a dependency rather than a forked version of the library, which means it is now possible to use enzyme's shallow with React Native components.

How do you write test cases using Enzyme and Jest?

Write a test – First, you are going to write a test for every possible challenge. Run the test – Write the minimum code required to pass the test. Refactor your code – Improvise on the code quality. Repeat the process – Now repeat this process for every new feature you introduce in the application.


1 Answers

Enzyme does not support React-Native, because it's rendered differently and doesn't use the DOM. That's why you're getting the error ReferenceError: document is not defined. You can see this issue for more information. The React team is currently working to expose a .find() method in react-test-renderer to simulate actions on components. Then it should work for both React/React-native without needing a DOM environment.

There's a hack you can do (and that's what we did in our company) that is rendering a custom component that extends TouchableOpacity and map onClick to call onPress. Something like this:

const mockPressable = (name) => {
  const RealComponent = require.requireActual(name);

  class Component extends RealComponent {

    render() {
      return React.createElement(
        RealComponent.displayName || RealComponent.name,
        { ...this.props, onClick: this.props.onPress },
        this.props.children
      );
    }

  }

  return Component;
};


jest.mock('TouchableOpacity', () => mockPressable('TouchableOpacity'));

And in your test code, you call component.simulate('click').

It's a hack and I'm not sure what are the consequences of doing this but it has worked for our use cases.

like image 172
Lucas Avatar answered Sep 19 '22 16:09

Lucas