Subscribe to RSS Feed

This post is written by Charlie Crawford who teaches for appendTo, who offers React Training Courses for developer teams.

There are many things to love about React, but one of the biggest pain points in React is project bootstrapping. As React takes a modular "roll your own" framework approach, it can take some time to get your project boilerplate up and running. Thankfully, create-react-app has come to the scene with powerful configuration free React boilerplate. While create-react-app tries to remain fairly agnostic and unopinionated, over time more and more functionality has been introduced into the project. Specifically, testing has progressed with the new revamped version of Jest (The "official" Facebook React testing tool) That being said, Enzyme (A popular third party React testing library by AirBnB) is still a vital part of the React testing stack. It can be a little unclear how create-react-app, Jest, and Enzyme should work Together. The official guide offers some insights on how to load Enzyme into your project, but doesn’t really explain the role Enzyme plays. Let’s change that.

What Enzyme brings to the the table

Enzyme brings all sorts of utility functions for testing React applications. However, the biggest benefit of using Enzyme is "shallow-rendering". Shallow rendering allows you to render a component, without rendering its children. This allows proper unit testing of React components. Let's say you are writing unit tests for a function a which invokes function b. If they are true unit tests - and not integration, end-to-end, or some other form of testing - the implementation of function b should not affect the unit tests of function a. Analogously, if you have React component A which renders sub-components B and C, you don't want the implementation of B and C affecting the unit tests for component A. Shallow rending is what makes this possible. Let’s see it in action with the beginnings of a typical Todo List app.

The app we will be building

We will be using vanilla React for this application. While this could easily be extended to Redux or other state management solutions, we will keep this tutorial focused on component testing. The app will consist of an App, TodoList, and Todo component. We will be bootstrapping this app with create-react-app, and will be using Enzyme and shallow rendering to facilitate writing true unit tests for the todoList component.

To begin, globally install create-react-app using yarn or npm. After installing, use the create-react-app to bootstrap the new application.

npm install -g create-react-app
create-react-app todo-testing

 

cd into the todo-testing app directory and install enzyme

cd todo-testing
npm install --save enzyme react-addons-test-utils

 

cd into the src directory, and create the few files

cd src
touch Todo.js TodoList.js Todo.test.js TodoList.test.js

 

Go into App.js component, and tell it to render our future TodoList component.

import React, { Component } from 'react';
import './App.css';
import TodoList from './TodoList';
 
class App extends Component {
  render() {
    return (
      <div className="App">
        <TodoList/>
      </div>
    );
  }
}
 
export default App;

 

Next, let's write the TodoList Component.

import React, { Component } from 'react';
import Todo from './Todo'
 
class TodoList extends Component {
  constructor() {
    this.todos = [];
  }
 
  addTodo(todo) {
    this.setState({todos: this.todos.concat(todo)});
  }
 
  render() {
    return (
      <div className="App">
        <p>Our Todo List</p>
        {this.todos.map(todo => <Todo todo={todo}/>)}
      </div>
    );
  }
}
 
export default TodoList;

 

Before writing test cases for TodoList, let's stub out a Todo component
so our code will compile.

import React, { Component } from 'react';
 
const Todo = () => (
  <div></div>
);
 
export default Todo;

 

We can now write a testcase in TodoList.test.js

import React from 'react';
import { shallow } from 'enzyme';
import TodoList from './TodoList';
 
it('renders "Our Todo List"', () => {
  const wrapper = shallow(<TodoList/>);
  const textHeader = <p>Our Todo List</p>;
  expect(wrapper.contains(textHeader)).toEqual(true);
});

 

npm test
Formatted test output

 

In addition to tests that use shallow rendering running much faster, the implementation of subcomponents largely won't affect the result of the unit test for this component. For example, let's change the implementation of the Todo component, and rerun the test

import React, { Component } from 'react';
 
const Todo = '';
 
export default Todo;

 

npm test
Formatted test output

 

Despite Todo not even being a real React component, our unit test for TodoList still runs and passes! Now you can achieve truly isolated unit testing of your components, and improve the reliability of your React applications.

 


Rss Commenti

No comments yet

No comments yet.

Sorry, the comment form is closed at this time.