Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test a button click in React with TypeScript, Jest and Enzyme

I'm building a React Native app with TypeScript. I'm doing my component tests using Jest and Enzyme. I'm also using React Navigation

I'm struggling to write the unit test for clicking my button.

Here is the component's code (just the render function):

  render() {
    const { navigation } = this.props;
    return (
      <View style={styles.container}>
        <Button
          raised
          title={strings.painButtonTitle}
          buttonStyle={styles.painButton}
          titleStyle={styles.title}
          onPress={() => navigation.navigate("QuestionsScreen")}
        />
      </View>
    );
  }

Now here is the unit test.

  describe("interaction", () => {
    let wrapper: ShallowWrapper;
    let props: Props;
    beforeEach(() => {
      props = createTestProps({});
      wrapper = shallow(<HomeScreen {...props} />);
    });

    describe("clicking the Pain Button", () => {
      it("should navigate to the 'QuestionsScreen'", () => {
        wrapper.find("Button").simulate("click");

        expect(props.navigation.navigate).toHaveBeenCalledTimes(1);
      });
    });
  });

This fails and claims the navigation.navigate function - which is mocked using jest.fn() - is never called.

I assume it has something to do with providing an error function to the button. The problem is, I can't not do that, since I need to call with the argument "QuestionsScreen". So I can't do something like onPress={this.navigation.navigate) and then miraculously call "QuestionsScreen", can I?

How can I get this test to pass?

like image 948
J. Hesters Avatar asked Oct 07 '18 20:10

J. Hesters


People also ask

How do you test a button in react Jest?

Step 1: You will start a new project using create-react-app so open your terminal and type. Step 2: Switch to the jest-testing folder using the following command. Step 6: Create a Button. js file and Button.

How would you test the react components using Jest and enzymes?

Both Jest and Enzyme are meant to test the react applications. Jest can be used with any other Javascript framework, but Enzyme is meant to run on react only. Jest can be used without Enzyme, and snapshots can be created and tested perfectly fine. But the Enzyme adds additional functionality to it.


1 Answers

The "Common Gotchas" section for simulate says that "even though the name would imply this simulates an actual event, .simulate() will in fact target the component's prop based on the event you give it. For example, .simulate('click') will actually get the onClick prop and call it."

That behavior can be seen in the Enzyme source code here and here.

So the line wrapper.find("Button").simulate("click"); ends up trying to call the onClick prop of the Button which doesn't exist so it essentially does nothing.

This post from an Airbnb dev recommends invoking props directly and avoiding simulate.

Here is a modified test that invokes the onPress prop directly:

it("should navigate to the 'QuestionsScreen'", () => {
  wrapper.find(Button).props().onPress({} as any);

  expect(props.navigation.navigate).toHaveBeenCalledTimes(1);   // SUCCESS
});
like image 108
Brian Adams Avatar answered Sep 30 '22 18:09

Brian Adams