Reputation: 28692
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
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