Setting up Jest for testing operations in a Next.JS project

How do we setting up Jest to test operations in Next.JS project? Let's write a simple test.

First, let's create a Next.js project:

npx create-next-app@latest my-next-app --typescript
cd my-next-app

Let's install Jest and the necessary libraries

npm install --save-dev jest
npm install --save-dev @types/jest
npm install --save-dev jest-environment-jsdom
npm install --save-dev @testing-library/react
npm install --save-dev @testing-library/jest-dom
npm install --save-dev @testing-library/user-event

Let's update the package.json file to run tests with Jest

"scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint",
    "test": "jest --watch"
}

Let's create the jest.config.js file

// jest.config.js

const nextJest = require("next/jest");

const createJestConfig = nextJest({
  dir: "./",
});

const customJestConfig = {
  setupFilesAfterEnv: ["<rootDir>/jest.setup.ts"],
  testEnvironment: "jsdom",
};

module.exports = createJestConfig(customJestConfig);

Let's create the jest.setup.ts file

// jest.setup.ts

import '@testing-library/jest-dom';

Let's create a components in the "components" folder. Let it be named "Counter" and have the codes as follows.

// Counter.tsx

'use client'
import { useState } from 'react'

export const Counter = () => {
  const [count, setCount] = useState(0);
  const [firstValue, setFirstValue] = useState(0);
  return (
    <div>
      <div className="mb-4 text-xl text-red-700" data-testid="result">
        {count}
      </div>
      <button onClick={() => setCount(count + 1)} className="bg-blue-700 text-white">
        Increment
      </button>
      <input
        type="number"
        name="firstValue"
        value={firstValue}
        onChange={(e) => setFirstValue(parseInt(e.target.value))}
        className="ml-4 mr-4 bg-gray-100 text-blue-700"
      />
      <button className="bg-blue-700 text-white" onClick={() => setCount(firstValue)}>
        Set First Value
      </button>
    </div>
  )
}

Let's create the test file of this component. Counter.test.tsx

// Counter.test.tsx

import { render, screen } from '@testing-library/react'
import user from '@testing-library/user-event'

import { Counter } from './Counter'

describe("Counter Tests", () => {
  test("the component should be render", () => {
    render(<Counter />);
    const countElement = screen.getByTestId("result");
    expect(countElement).toBeInTheDocument();
    const incrementButton = screen.getByRole("button", { name: "Increment" });
    expect(incrementButton).toBeInTheDocument();
    const amountInput = screen.getByRole("spinbutton");
    expect(amountInput).toBeInTheDocument();
    const setButton = screen.getByRole("button", { name: "Set First Value" });
    expect(setButton).toBeInTheDocument();
  });

  test("the result should be 0", () => {
    render(<Counter />);
    const countElement = screen.getByTestId("result");
    expect(countElement).toHaveTextContent("0");
  });

  test("the result should be 1 after clicking the Increment button", async () => {
    user.setup();
    render(<Counter />);
    const incrementButton = screen.getByRole("button", { name: "Increment" });
    await user.click(incrementButton);
    const countElement = screen.getByTestId("result");
    expect(countElement).toHaveTextContent("1");
  });

  test("the result should be 3 after clicking the Increment button 3 times", async () => {
    user.setup();
    render(<Counter />);
    const incrementButton = screen.getByRole("button", { name: "Increment" });
    await user.click(incrementButton);
    await user.click(incrementButton);
    await user.click(incrementButton);
    const countElement = screen.getByTestId("result");
    expect(countElement).toHaveTextContent("3");
  });

  test("the result should be 5 after clicking the Set Initial Value button", async () => {
    user.setup();
    render(<Counter />);
    const firstValueInput = screen.getByRole("spinbutton");
    await user.type(firstValueInput, "5");
    expect(firstValueInput).toHaveValue(5);
    const setButton = screen.getByRole("button", { name: "Set First Value" });
    await user.click(setButton);
    const countElement = screen.getByTestId("result");
    expect(countElement).toHaveTextContent("5");
  });
});

We integrated Jest into our project and created a test file.

Now all we need to do is write the following command on the terminal screen.

npm test

I explain in detail what the commands in the test file do in my future articles. For now, we have learned how to install Jest in a next.js project.

You can use the link below to access the codes of the project.

Github repository

Good coding...