Richard B. Kaufman-López

A simple structure to test React components in Jest

January 17, 2018

A file showing Jest tests

Each and every time I write a test for a React component, I’ve found myself using the same structure over and over when testing React components.

Let’s consider an Icon component that accepts a prop name.

import React from "react"
export default function Icon({ name }) {
  const className = `icon-${name}`
  return <i className={className} />
}

And its corresponding test:

import React from "react"
import { shallow } from "enzyme"

import Icon from "./Icon"

describe("Icon", () => {
  let tree, props

  const buildTree = (newProps = {}) => {
    const defaultProps = {
      name: "add",
    }

    props = Object.assign({}, defaultProps, newProps)

    return shallow(<Icon {...props} />)
  }

  it("matches the snapshot", () => {
    tree = buildTree()
    expect(tree).toMatchSnapshot()
  })

  it("adds the proper className given an icon name", () => {
    tree = buildTree({ name: "delete" })

    expect(tree.hasClass("icon-delete")).toBe(true)
  })
})

The key here is the buildTree function. This function will be used throughout all the test cases. It helps us define the instance of the component given a minimal amount of typing.

Calling buildTree without arguments will return a ‘default’ instance of the component. What we mean by ‘default’ is up to us. However, we can an new props inside an object. This object will merge with the defaultProps and return a component with the props we defined.

In the Icon example, we tested the default case for an Icon component with a snapshot. In our second test case, we tested specifically to check if the resulting element did indeed have the className we expect it to have. To do that we explicitly passed a new name.

buildTree will prove very useful for more complex components, specially those with many props, and therefore possibly many test cases. By having a simple way to create instances of our component we can keep our code short and brief and consequently keep our test code clean.