Skip to the content.
22 December 2022
Writing automated tests helps ensure your code behaves exactly as expected and remains reliable over time. [Jest](https://jestjs.io/) is a popular JavaScript testing framework that provides a complete testing solution with a built-in test runner, assertion library, and mocking utilities. This guide walk you through setting up Jest and testing both plain JavaScript and React components. To install Jest along with the Enzyme utility library, run: ```bash # npm npm install --save-dev jest enzyme # yarn yarn add --dev jest enzyme ``` Configure Jest to use a browser environment by adding a `jest` block to your `package.json` file: ```json { "jest": { "testEnvironment": "jsdom" } } ``` This configuration tells Jest to run your tests inside a simulated browser environment called **jsdom**, which allows you to interact with DOM elements directly in your test suites. Next, add a test script to your `package.json`: ```json "scripts": { "test": "jest" } ``` Now you can start your tests from the command line: ```bash yarn test ``` ## Testing plain JavaScript With Jest installed and configured, you can start writing your first test suite. Jest uses a readable, descriptive syntax. Here is a simple example: ```javascript describe("basic calculations", () => { it("adds numbers correctly", () => { expect(1 + 1).toBe(2); }); it("identifies math errors", () => { expect(1 + 1).toBe(3); }); }); ``` The `describe` function groups related tests into a single suite, while `it` defines an individual test block. The `expect` function allows you to write assertions. You can use `beforeEach` and `afterEach` hooks to set up common test states and keep your suites clean: ```javascript describe("user configuration", () => { let role; beforeEach(() => { role = "admin"; }); it("reads the default role", () => { expect(role).toBe("admin"); }); it("allows updating the role", () => { role = "editor"; expect(role).toBe("editor"); }); }); ``` Using `beforeEach` resets the `role` variable before every test, preventing state from leaking between tests. Jest includes many matching functions like `toBe` for strict equality and `toEqual` for deep object comparisons: ```javascript it("verifies strict and soft equality", () => { expect(1).toBe(1); expect(1).not.toBe("1"); }); ``` ## Testing React components Testing React components involves rendering them in a test environment and making assertions about their visual output or behavior. Import your component and render it to a DOM container in your test: ```jsx import React from "react"; import ReactDOM from "react-dom"; import MyComponent from "./MyComponent"; it("renders without crashing", () => { const div = document.createElement("div"); ReactDOM.render(, div); }); ``` ### Snapshot testing Snapshot tests prevent unexpected changes to your component's rendered output by saving a text representation of the HTML and comparing it to subsequent test runs. ```jsx import React from "react"; import MyComponent from "./MyComponent"; import renderer from "react-test-renderer"; it("renders correctly", () => { const tree = renderer.create().toJSON(); expect(tree).toMatchSnapshot(); }); ``` If you make deliberate changes to the component's UI, Jest will flag the diff, and you can update the stored snapshot from your terminal. ### Testing mock functions You can mock modules or functions to isolate the component you are testing. This is ideal when your component fetches data from a database or relies on external APIs. ```jsx import React from "react"; import MyComponent from "./MyComponent"; import * as api from "./api"; jest.mock("./api"); it("calls the API when mounted", () => { const spy = jest.spyOn(api, "getData"); const wrapper = mount(); expect(spy).toHaveBeenCalled(); }); ``` ### Testing interactive events You can simulate user interactions like button clicks or form submissions, then assert that the component reacted correctly. ```jsx import React from "react"; import { shallow } from "enzyme"; import MyComponent from "./MyComponent"; it("triggers the click handler", () => { const mockClickHandler = jest.fn(); const wrapper = shallow(); wrapper.find("button").simulate("click"); expect(mockClickHandler).toHaveBeenCalled(); }); ``` This shallow-renders your component, finds the button element, simulates a click event, and asserts that the mock click handler was called. You can simulate other DOM events in exactly the same way: ```jsx import React from "react"; import { shallow } from "enzyme"; import MyComponent from "./MyComponent"; it("triggers the submit handler", () => { const mockSubmitHandler = jest.fn(); const wrapper = shallow(); wrapper.find("form").simulate("submit"); expect(mockSubmitHandler).toHaveBeenCalled(); }); ``` ### Helpful resources - [Jest React testing tutorial](https://jestjs.io/docs/tutorial-react)