Testing with Enzyme

Linked Projects:

Calreact
 
Lesson code - https://github.com/learnetto/calreact-frontend/tree/m10l2-enzyme

Next, we want to test components, for example, whether a particular component contains a piece of text or element that we are interested in. 

For this, we’re going to use a library called Enzyme. Enzyme is a testing utility for React which makes it easy to assert, manipulate, and traverse React Components' output. It works well with Jest.

Let’s install Enzyme by running

npm install —save-dev enzyme react-addons-test-utils

Now, let’s get the test running with

npm test

One of the testing tools which React provides is shallow rendering. Shallow rendering only tests the given component and makes sure that any child components do not affect the test.

Enzyme provides a simple shallow rendering API.

Let’s try it for the first test we wrote.

First, let’s import shallow from Enzyme:

import React from 'react';
  import ReactDOM from 'react-dom';
  import Appointment from '../components/Appointment';
  import { BrowserRouter as Router } from 'react-router-dom';
  import { shallow } from 'enzyme';

And then we can write the test by just having the shallow call:

it('renders without crashing', () => {
   shallow(<Appointment />);
  });

We don’t need the div and the router either.

In the video, you can see some warnings appearing when you run the test.

[screenshot 1:22-23]

 It's because I’m using a slightly older version of React, but that shouldn’t affect the tests so you can ignore the warnings.

Now, let’s test the render function of our component in a bit more depth.

To do that, underneath our shallow call, add

describe('render', () )

Then, let's write a test which checks if the title of an appointment is rendered correctly:

describe('render', () => {
  	it('should display the appointment title', () => {
 
Underneath that, I’m going to paste in a couple of lines of code.

First, we’re declaring a const called appointment:

describe('render', () => {
  	it('should display the appointment title', () => {
 const appointment = mount(<Router><Appointment appointment={{id:1, title: 'Team standup meeting', appt_time: new Date()}} /></Router>);
   const title = <h3>Team standup meeting</h3>;

and we’re using mount which is a method provided by Enzyme for full rendering (as opposed to shallow rendering).

So the code states

mount(<Router><Appointment appointment={{

and we pass an appointment prop  with an id, title and appt_time value:

 const appointment = mount(<Router><Appointment appointment={{id:1, title: 'Team standup meeting', appt_time: new Date()}} /></Router>);

Then, we declare another const, title, which contains the JSX that should be rendered:

 const appointment = mount(<Router><Appointment appointment={{id:1, title: 'Team standup meeting', appt_time: new Date()}} /></Router>);
  const title = <h3>Team standup meeting</h3>;

And then we’ll write an assertion to see if they match:

describe('render', () => {
  	it('should display the appointment title', () => {
   const appointment = mount(<Router><Appointment appointment={{id:1, title: 'Team standup meeting', appt_time: new Date()}} /></Router>);
   const title = <h3>Team standup meeting</h3>;
  		expect(appointment.contains(title)).toEqual(true);
  	})

For the test to run correctly, we need to import mount next to the shallow import at the top of our code file:

 import { shallow, mount } from 'enzyme';

Now we can test whether the test works - yes, our test passes.

Now, let’s write another test, this time for the appointment time.

Let's make a copy of the test that we used for describe('render'):

describe('render', () => {
  	it('should display the appointment title', () => {
   const appointment = mount(<Router><Appointment appointment={{id:1, title: 'Team standup meeting', appt_time: new Date()}} /></Router>);
   const title = <h3>Team standup meeting</h3>;
  		expect(appointment.contains(title)).toEqual(true);
  	})

...change title to time:

describe('render', () => {
  	it('should display the appointment time', () => {
   const appointment = mount(<Router><Appointment appointment={{id:1, title: 'Team standup meeting', appt_time: new Date()}} /></Router>);
   const title = <h3>Team standup meeting</h3>;
  		expect(appointment.contains(title)).toEqual(true);
  	})

Let’s also specify a datetime and appt_time in the <p> tags so that it’s easier to test:

it('should display the appointment time', () => {
  const appointment = mount(<Router><Appointment appointment={{id:1, title: 'Team standup meeting', appt_time: new Date('04/11/2017, 12:00:00')}} /></Router>);
   const appt_time = <p>April 11 2017, 12:00:00 pm</p>;
  expect(appointment.contains(appt_time)).toEqual(true);
  })
  });

When I hit save, the test auto runs and it passes.

That's a brief introduction to testing React components with Enzyme.

Liked this tutorial? Get more like this in your inbox