user1584120
user1584120

Reputation: 1261

how to test a child component in react

I am trying to test a react component that has a child component. The child has an input box which will update its state with onChange, then onSubmit will callback to the parent the text updating the parent state. The components look like this:

class App extends Component {

constructor(props) {
  super(props)
  this.state = {answer: ''};
}

answerHandler(_answer) {
  this.setState({
    answer: _answer
  })
}

render() {
  return (
    <div className='App'>
    <Letters answerHandler={this.answerHandler.bind(this)}/>
  </div>
);
}
}
export default App;

_

class Letters extends Component {
  constructor(props) {
    super(props);
    this.state = {value: ''};

    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleChange(event) {
    this.setState({value: event.target.value});
  }

  handleSubmit(event) {
    event.preventDefault()
      this.props.answerHandler(response.data.word)
  }

  render() {
    return (
      <div className="Letters">
        <form onSubmit={this.handleSubmit}>
        <label>
          Letters:
          <input type="text" value={this.state.value} onChange={this.handleChange} />
        </label>
      <input type="submit" value="Submit" />
    </form>
  </div>
  );
  }
 }

export default Letters;

When running the test I get a message:Method “simulate” is only meant to be run on a single node. 2 found instead.

it('enter letters and check answer', () => {
  const wrapper = mount(<App />);
  wrapper.find('input').simulate('change', { target: { value: 'doof' }});
})

I'm not entirely sure what this means. I thought enzyme's mount should create the app with all the components? If I use shallow instead of mount it says 0 nodes instead of 2. From looking around it seems to suggest that I spy the callback but this seems odd that you can't test components together so I'm sure I'm doing something wrong.

Upvotes: 0

Views: 4391

Answers (1)

jb cazaux
jb cazaux

Reputation: 320

you have 2 inputs fields:

<input type="text" value={this.state.value} onChange={this.handleChange} />
<input type="submit" value="Submit" />

so enzyme doesnt know on which simulate. try

wrapper.find('input').at(0).simulate('change', { target: { value: 'doof' }});

const component = shallow(<MyComponent/>); component.state('name') will give you the name attribute of the state.

By the way, I prefer to test components individually, using 'shallow' rather than 'mount'. It will be much easier to test and tests will be less fragiles. But it s not your question :)

Upvotes: 4

Related Questions