Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test arrow function in React ES6 class

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!

like image 353
Leo Hsieh Avatar asked Jun 30 '16 17:06

Leo Hsieh


People also ask

Are arrow functions ES6?

Arrow functions were introduced in ES6.

What does => in React mean?

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.

Can you use arrow functions in React?

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.


1 Answers

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()
      });
    });
  • Test their functionality by simulating actions that will invoke these functions and test for the expected behavior

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.

like image 128
dondrzzy Avatar answered Sep 24 '22 19:09

dondrzzy