Testing React Components

The @testing-library/react library includes several helpers on top of react-dom and react-dom/test-utils to aid in ensuring that whenever the implementation (though not the functionality) of your component evolves, your tests won’t break. If you followed the steps in the previous section to install and configure Jest, you can pick up right here. Otherwise, check to ensure that you have Jest installed and configured correctly for your Gatsby site.

First, you’ll need to install several additional development dependencies (devDependencies):

$ npm install --save-dev @testing-library/react @testing-library/jest-dom

At the root of your project, in the same directory as package.json and gatsby-config.js, create a new file named setup-test-env.js containing the following import:

// setup-test-env.js
import "@testing-library/jest-dom/extend-expect"

Because this JavaScript file is executed every time Jest runs a test, you don’t need to add this import statement to every single test file. Now, you need to make Jest aware of this file and indicate its location. If your jest.config.js file is in the same state it was in at the end of the previous section, all you need to do is add a new key, setupFilesAfterEnv, to the module.exports object and identify the file you just created:

// jest.config.js
module.exports = {
  // Other Jest configuration.
  setupFiles: [`<rootDir>/loadershim.js`],
  setupFilesAfterEnv: ["<rootDir>/setup-test-env.js"],
}

Now, you can write tests that use @testing-library/react instead of react-test-renderer, and you have access to a much richer range of methods to use to introspect the rendered DOM elements and ensure they match your snapshots. Here is one example of a rudimentary test that ensures our <Bio /> component contains a particular string as opposed to the child elements it comes with by default in the unmodified Gatsby blog starter:

// src/components/__tests__/bio.js
import React from "react"
import { render } from "@testing-library/react"

const Bio = () => (
  <div className="bio" data-testid="main-bio">
    Hello! This is my bio!
  </div>
)

test("Displays the correct title", () => {
  const { getByTestId } = render(<Bio />)
  // The next line describes our assertion.
  expect(getByTestId("main-bio"))
    .toHaveTextContent("Hello! This is my bio!")
})

We’ve covered unit tests at a high level in this section, but that doesn’t mean unit testing is the only type of testing you should be concerned with. For small-scale testing, unit tests do the trick, but sometimes it’s important to have a more holistic view of the visual design of your components as well as a sense of how your site performs end-to-end across multiple pages. We’ll turn our attention to these two types of tests next.

NOTE

Gatsby pages and components containing GraphQL queries require special handling, covered in the Gatsby documentation’s guide to testing components with GraphQL. For additional information, consult the documentation for @testing-library/react and custom Jest matchers in @testing-library/jest-dom.


Posted

in

,

by

Tags:

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *