ReactJS/Jest: How to test/mock a function, which is passed to component


I'm trying to do some unit testing using jest/enzyme for my react components.

But I'm facing problems with an function I'm passing to a second component. I don't understand if I have to test or mock this function. If I have to mock it, I don't know how to do that for a function.

Parent Component

export default class Parent extends Component {
  togglePosition (term, event) {
    this.setState({
      top: term.length >= 3
    })
  }

  render () {
    return (
      <div>
        <Child togglePosition={this.togglePosition} />
      </div>
    )
  }
}

Child component

export default class Child extends Component {
  handleChange (event) {
    const term = event.target.value
    this.props.togglePosition(term) // <-- Test/mock it?
    this.setState({
      loading: 'loading',
      term
    })
  }

  render () {
    return (
      <div>
        <Input id="target-input" onChange={this.handleChange} />
      </div>
    )
  }
}

This is how I do a test for the Child component - testing handleChange:

Unit test (Child)

it('handleChange() should set state.term', () => {
  const event = { target: { value: 'test' } }
  const wrapper = shallow(<Child />)

  wrapper.find('#target-input').simulate('change', event)
  const state = wrapper.instance().state
  expect(state).toEqual({ loading: 'loading', term: 'test' })
})

Do get this error: TypeError: this.props.togglePosition is not a function

Without actually testing it, I believe this is what you need:

it('handleChange() should set state.term', () => {
  const togglePosition = jest.fn();
  const event = { target: { value: 'test' } };
  const wrapper = shallow(<Child togglePosition={togglePosition} />);

  wrapper.find('#target-input').simulate('change', event);
  const state = wrapper.instance().state;
  expect(state).toEqual({ loading: 'loading', term: 'test' });
  expect(togglePosition).toHaveBeenCalledWith('test');
})

Mock the passed function: const togglePosition = jest.fn();, and test the condition/response: expect(togglePosition).toHaveBeenCalledWith('test');.