Events in JavaScript are of many types. Popular events being mouse events - click, mouse-over, mouse-down and drag/drop events, form events, focus events, network events and custom events as well.

In this article, we are going to write a React class with on click button event, and we are then going to write a unit test case for it using jest. The unit test case for testing other kinds of events will be similar.

We are going to test the "click", "mouseover" and "mouseleave" event. See the example below for the sample React app.

import React, { Component } from 'react';
class App extends Component {
  
  showlog = () => {
    console.log('button clicked');
  }

  render(){
    return (
      <div className="App">
        <button onClick={this.showlog} onMouseOver={this.showlog} onMouseLeave={this.showlog}>Show log</button>
      </div>
    );
  }
}

export default App;

Let us see the unit test case for the above component. We will go through the details of it after.

import React from 'react';
import { shallow, configure } from "enzyme";
import App from './App';
import Adapter from 'enzyme-adapter-react-16';

configure({ adapter: new Adapter() });

it('show log on click', () => {
  const app = shallow(<App />);
  const spy = jest.spyOn(app.instance(), "showlog");
  app.instance().forceUpdate();
  app.find("button").simulate("click");
  expect(spy).toHaveBeenCalled();
});

it('show log on mouse over', () => {
  const app = shallow(<App />);
  const spy = jest.spyOn(app.instance(), "showlog");
  app.instance().forceUpdate();
  app.find("button").simulate("mouseover");
  expect(spy).toHaveBeenCalled();
});

it('show log on mouse leave', () => {
  const app = shallow(<App />);
  const spy = jest.spyOn(app.instance(), "showlog");
  app.instance().forceUpdate();
  app.find("button").simulate("mouseleave");
  expect(spy).toHaveBeenCalled();
});

Let us consider the first unit test case. We are spying on the showlog function. Then we update the instance of the app.

const spy = jest.spyOn(app.instance(), "showlog");
app.instance().forceUpdate();

We fire the events using the simulate function.

app.find("button").simulate("click");

When the click event is simulated, the spy function is called. So we test it using toHaveBeenCalled

We can similarly test other events as follows

app.find("button").simulate("click");
app.find("button").simulate("mouseover");
app.find("button").simulate("mouseleave");

Passing arguments to the event function

If you want to pass data to the event callback function, and test it out, you can pass second argument to the simulate function.

Let us modify the above React class to accept the data

import React, { Component } from 'react';
class App extends Component {
  
  showlog = (data) => {
    console.log('button clicked', data);
  }

  render(){
    return (
      <div className="App">
        <button onClick={this.showlog} onMouseOver={this.showlog} onMouseLeave={this.showlog}>Show log</button>
      </div>
    );
  }
}

export default App;

In order to test it out, we will pass data as second argument to simulate function and use toHaveBeenCalledWith to check if the spy function has been called with data.

it('show log on click with data', () => {
  const app = shallow(<App />);
  const spy = jest.spyOn(app.instance(), "showlog");
  app.instance().forceUpdate();
  const data = {
    name: 'techdomain'
  }
  app.find("button").simulate("click", data);
  expect(spy).toHaveBeenCalledWith(data);
});

Conclusion

So in the above article, we saw how to use simulate function from enzyme to test the various events and also test out the data to the event.