YPCrumble
YPCrumble

Reputation: 28692

How do I mock a class method callback called via an onClick event in React/Enzyme?

I have the following simple React component:

import React, { Component } from 'react'

class Button extends Component {
  constructor (props) {
    super(props)
    this.handleClick.bind(this)
  }

  handleClick () {
    console.log('clicked')
  }

  render () {
    return (
      <button onClick={this.handleClick}>Test</button>
    )
  }
}

export default Button

And the following test:

import React from 'react'
import { shallow } from 'enzyme'
import Button from './button'
import Adapter from 'enzyme-adapter-react-16'

import Enzyme from 'enzyme'
Enzyme.configure({ adapter: new Adapter() })

it('handles a click event', () => {
  const button = shallow(<Button />)
  button.instance().handleClick = jest.fn()
  button.find('button').simulate('click')
  expect(button.instance().handleClick).toHaveBeenCalledWith()
})

The test is failing because the handleClick mock has not been called. I'm guessing this is because my mock is being placed after this.handleClick has been rendered, and so it's not mocking the handleClick class method on the instance. However, I can't seem to figure out how to make this work.

What I'm trying to understand is why this code doesn't work, and how to make the unit test work.

Upvotes: 0

Views: 521

Answers (1)

kooskoos
kooskoos

Reputation: 4859

You should mock the function before shallow/mount.
So that shallow/mount component uses your mocked function and not the original function.

describe("Foo", () => {

    it("should bubble the event up and call parent's handleClick", () => {
        const handleClick = jest.spyOn(Foo.prototype, 'handleClick') //spy on handleClick function
        const wrapper = mount(<Foo />);
        wrapper.find('button').simulate('click'); //finding the button and simulating click
        expect(handleClick).toHaveBeenCalledTimes(1) //verify function was called after click simulation
    })

})

Check out a working example here https://codesandbox.io/s/flamboyant-babbage-tl8ub

Note : Go into the tests tab to run all tests.

Hope that clarifies it!

Upvotes: 1

Related Questions