I used arrow function inside of my React component to avoid binding this context, for example my component look like this;
class Comp extends Component {
_fn1 = () => {}
_fn2 = () => {}
render() {
return (<div></div>);
}
}
How do I test _fn1
and _fn2
function in my test cases? Because these kind of function did not associated with React component itself, so when I do
fnStub = sandbox.stub(Comp.prototype, "_fn1");
it is not going work, since _fn
did not bind with Comp.prototype
. Thus, how can I test those functions in React if I want to create function with arrow syntax? Thanks!
Arrow functions were introduced in ES6.
The () => { ... } is the function. It's an ES6-style "arrow" function expression. These are like function expressions ( tick = function() { ... } ) except that the this value within the function is inherited from the context in which it's defined rather than being set when the function is called.
Arrow functions in class properties Since arrow class properties are still in a proposal stage, it is understandable that official React documentation doesn't use them.
ES6 functions or arrow functions are not added to the class prototype. However, there are a couple of ways to test them:-
Test that the functions themselves are called when a suitable event occurs ES5 functions exist on the class prototype and something like this is possible:
import Component from 'path/to/component';
import { shallow } from 'enzyme';
describe(<Component>, () => {
it('should call handleSubmit', () => {
const spy = jest.spyOn(Component.prototype, 'handleSubmit');
const wrapper = shallow(<Component />);
...
//Invoke handleSubmit
...
expect(spy).toBeCalled()
});
});
whereas ES6 functions exist on the instance of the mounted component(you can also use shallow)
import Component from 'path/to/component';
import { mount } from 'enzyme';
describe(<Component>, () => {
it('should call handleSubmit', () => {
const wrapper = mount(<Component />);
...
const spy = jest.spyOn(wrapper.instance(), 'handleSubmit');
//update the instance with the new spy
wrapper.instance().forceUpdate();
...
//invoke handleSubmit
expect(spy).toBeCalled()
});
});
Assuming component content such as:
state = {
title: 'Current Title'
};
updateTitle = (event) => {
title = event.target.value;
this.setState({ title });
}
render() {
return (
<div>
<input type="text" value={this.state.title} onChange={this.updateTitle} />
<div>
)
}
Test
...
wrapper.find('input').simulate('change', {target: {value: 'New title'}});
expect(wrapper.state().title).toBe('New Title');
...
I hope this helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With