Jest-mock fat arrow function in react component
Given my component and test below, why is my method confirmClickHandler
still getting called when my test is running?
Note. I noticed that when I change the method from a fat arrow function to just a regular function, it gets mocked correctly. What am I missing here?
class CalendarConfirmation extends React.Component {
...
confirmClickHandler = (e) => {
...
}
}
and my test:
import React from 'react';
import {mount} from 'enzyme';
import CalendarConfirmation from '../components/CalendarConfirmation';
describe('Test CalendarConfirmation', () => {
let calendarConfirmation;
calendarConfirmation = mount (<CalendarConfirmation />);
calendarConfirmation.instance().confirmClickHandler = jest.fn();
...
}
source to share
This works for me:
import React from 'react'
import { mount, shallow } from 'enzyme'
class Foo extends React.Component {
// babel transpiles this too Foo.prototype.canMock
protoMethod () {
// will be mocked
}
// this becomes an instance property
instanceMethod = () => {
return 'NOT be mocked'
}
render () {
return (<div>{`${this.protoMethod()} ${this.instanceMethod()}`}</div>)
}
}
Foo.prototype.protoMethod = jest.fn().mockReturnValue('you shall')
it('should be mocked', () => {
const mock = jest.fn().mockReturnValue('be mocked')
const wrapper = mount(<Foo />)
wrapper.instance().instanceMethod = mock
wrapper.update()
expect(mock).toHaveBeenCalled()
})
Note that this fails when used shallow
instead of mount.
source to share
You are not missing anything.
The jester can only mock the structure of objects that are present at the right time. This is done by reflection (not parsing), which means that properties that are added by the constructor cannot be modeled. It is important to understand that assigning a bold arrow in a class in JS is not a class method; it is a property of the class that contains a reference to the function.
source to share