Step Three: Events

Obviously we will have test cases where we will need to trigger events. How do we go about simulating click events and typing inside an input? TestUtils comes with a method called Simulate, which has a method for every React supported event.

Let’s try to simulate a click on an item and check the number of completed tasks, which should be one, then again clicking on the same item and setting the completed tasks to 0 again. We’re still using our mount function for this example, this time passing in the Root component and then simulating a click on the first component with class name ‘todo’.

import { scryRenderedDOMComponentsWithClass as findByClass }

from 'react-addons-test-utils'; it('should simulate click events', () => {

const app = mount(Root);

Simulate.click(findByClass(app, 'todo')[0]);

expect(findByClass(app, 'completed').length).toBe(1); Simulate.click(findByClass(app, 'todo')[0]);

expect(findByClass(app, 'completed').length).toBe(0);

});

Improving mount

What if we could refactor the mount function to return some methods to quickly iterate over the rendered DOM? Well let’s try to implement a naive mount function that does exactly that.

function mount(Component) {

const find =

findByClass.bind(null, renderIntoDocument(Component));

return {

find(selector, nth) {

const selection = (typeof nth === 'undefined')

? find(selector)

: find(selector)[nth]; return {

simulate(eventType) {

Simulate[eventType](selection);

}, length: selection? selection.length : undefined

}

}

};

}

The new mount function returns an object with a find method which we could use to search for DOM elements inside the rendered root component. The new function will not get us too far either, but simplifies the previous example.

it('mount should simulate click events with a better interface',

() => {

const app = mount(<Root />);

app.find('todo', 0).simulate('click');

expect(app.find('completed').length).toBe(1); app.find('todo', 0).simulate('click');

expect(app.find('completed').length).toBe(0);

});

We should have an idea on how to approach testing from a low level perspective now. The good news is that we don’t need to write our own wrapper to handle shallow and full DOM rendering. Enzyme is a library that takes care of abstracting away the low level utils and offers three different high level approaches to testing a React application. Shallow, mount and render. The three approaches expose a similar Api offering convenience functions to make writing tests more efficient as well as removing boilerplate along the way.