Leslie Alldridge
Leslie Alldridge

Reputation: 1585

Testing handle change function in React using Enzyme and Jest

My react component contains this code

 handleChange = e => {
    this.setState({
      num: e.target.value
    });
  };

  render() {
    return (
      <div>
        <h2>Delete cat :(</h2>
        <input
          onChange={this.handleChange}
          type="number"
          placeholder="enter id here"
        />
        <button id="deleteBtn" onClick={this.deleteOne}>
          Delete
        </button>
      </div>
    );
  }
}

As you can see, the handleChange function fires when the input changes and will update state from there.

How can I test this using Enzyme? I've tried

 it("Updates the state", () => {
     const wrapper = shallow(
       <Provider store={store}>
         <DeleteOne />
       </Provider>
     );
     const input = wrapper.find("input");

     input.simulate("change", { target: { num: 2} });

     expect(wrapper.state().num).toEqual(2);
   });
});

I had to attempt to wrap it in store because I'm using Redux and exporting a connected component. I've been Googling the last hour and trying all sorts but weren't able to get this test passing. Please send help :) cheers

PS: I've tested the button click no worries as it just runs a function (no state update).

Upvotes: 1

Views: 6691

Answers (1)

Brian Adams
Brian Adams

Reputation: 45780

I typically export both the connected component for use in the app, and the component itself for testing.

Looks like you've got a small typo, pass { target: { value: 2 } } as your event.

Here is a working example based on the code you provided:

import * as React from 'react';
import { shallow } from 'enzyme';

class DeleteOne extends React.Component {

  handleChange = e => {
    this.setState({
      num: e.target.value
    });
  };

  render() {
    return (
      <div>
        <h2>Delete cat :(</h2>
        <input
          onChange={this.handleChange}
          type="number"
          placeholder="enter id here"
        />
        <button id="deleteBtn" onClick={this.deleteOne}>
          Delete
      </button>
      </div>
    );
  }
}

it("Updates the state", () => {
  const wrapper = shallow(<DeleteOne />);
  const input = wrapper.find("input");
  input.simulate("change", { target: { value: 2 } });  // 'value' instead of 'num'
  expect(wrapper.state().num).toEqual(2);  // SUCCESS
});

Upvotes: 5

Related Questions