3

I am trying to test functionality in my component, the basic idea is some state is set and when a button is pressed a function is called with the set state. The code works but when I try to test this I don't get the expected result, it is as if the state never gets set during the test.

I am using a functional component with hooks (useState) in a React Native app tested with Jest and Enzyme.

An example which replicates my problem is:

import React, { useState } from "react";
import { View, Button } from "react-native";
import { shallow } from "enzyme";

const Example = function({ button2Press }) {
const [name, setName] = useState("");

  return (
    <View>
      <Button title="Button 1" onPress={() => setName("Hello")} />
      <Button title="Button 2" onPress={() => button2Press(name)} />
    </View>
  );
};

describe("Example", () => {
  it("updates the state", () => {
    const button2Press = jest.fn();
    const wrapper = shallow(<Example button2Press={button2Press} />)
    const button1 = wrapper.findWhere(node => node.prop("title") === "Button 1")
                        .first();
    const button2 = wrapper.findWhere(node => node.prop("title") === "Button 2")
                        .first();

    button1.props().onPress();
    button2.props().onPress();

    expect(button2Press).toHaveBeenCalledWith("Hello");
  });
});

Any help on what I am doing wrong/missing would be great.

1 Answer 1

21

The problem here is 2 things. First I need to call wrapper.update(); after performing actions will cause the state to update. Second I need to find the element again after performing wrapper.update(); for that element to have the updated state.

The working solution is:

import React, { useState } from "react";
import { View, Button } from "react-native";
import { shallow } from "enzyme";

const Example = function({ button2Press }) {
const [name, setName] = useState("");

  return (
    <View>
      <Button title="Button 1" onPress={() => setName("Hello")} />
      <Button title="Button 2" onPress={() => button2Press(name)} />
    </View>
  );
};

describe("Example", () => {
  it("updates the state", () => {
    const button2Press = jest.fn();
    const wrapper = shallow(<Example button2Press={button2Press} />)
    const button1 = wrapper.findWhere(node => node.prop("title") === "Button 1")
                        .first();
    button1.props().onPress();
    wrapper.update(); // <-- Make sure to update after changing the state

    const button2 = wrapper.findWhere(node => node.prop("title") === "Button 2")
                        .first(); // <-- Find the next element again after performing update
    button2.props().onPress();

    expect(button2Press).toHaveBeenCalledWith("Hello");
  });
});
Sign up to request clarification or add additional context in comments.

2 Comments

This answer was ridiculously hard to find!
Wow thank you!! I was stuck on this forever! In my situation, I didn't need to call wrapper.update() but I did need to find the element again.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.