Home > front end >  React Testing Library with Next.Js, unit test failing because of state?
React Testing Library with Next.Js, unit test failing because of state?

Time:12-18

I'm trying to create a unit test using react testing library jest in my nextjs app, it's a simples test, once a click on the button without fill the fields, it should show a error message "Please enter all fields", but I can't find the error message after the button is clicked, I think it might have something to do with the state, because once the button is clicked is going to set error true to show the message.

My register component:

import Head from "next/head";
import { useState } from "react";

const Register = () => {
  const [error, setError] = useState(false);
  const [showPass, setShowPass] = useState(false);

  const handleSubmit = async (event: React.SyntheticEvent) => {
    event.preventDefault();

    const name = (event?.target as any).nome?.value;
    const email = (event?.target as any).email?.value;
    const password = (event?.target as any).password?.value;

    if (name === "" || email === "" || password === "") {
      setError(true);
      return;
    }

    const data = {
      name,
      email,
      password,
    };

    const resp = await fetch("http://localhost:5000/register", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify(data),
    });

    const data2 = await resp.json();
  };

  return (
    <div className="center text-textLight">
      <Head>
        <title>Forum</title>
        <meta name="description" content="Generated by create next app" />
        <link rel="icon" href="/favicon.ico" />
      </Head>
      <h2 className="title mb-8">Register</h2>
      {error && <h2 className="text-error">Please enter all fields</h2>}
      <form onSubmit={handleSubmit}>
        <div>
          <input
            className="inputStyle mb-2"
            type="text"
            name="nome"
            placeholder="name"
          />
        </div>
        <div>
          <input
            className="inputStyle mb-2"
            type="text"
            name="email"
            placeholder="email"
          />
        </div>
        <div>
          <div>
            <input
              className="inputStyle dark:text-textLight"
              type={showPass ? "text" : "password"}
              name="password"
              placeholder="password"
            />
          </div>
          <div className="mt-2 flex items-center justify-center">
            <input
              onChange={() => setShowPass((prev) => !prev)}
              className="mr-2"
              type="checkbox"
              id="showPas"
              name="showPas"
            />
            <label className="dark:text-textDark" htmlFor="showPas">
              Show password
            </label>
          </div>
        </div>

        <button className="btn mt-6 dark:text-textDark">Submit</button>
      </form>
    </div>
  );
};

export default Register;

My test for register:

import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import Register from "../src/pages/register";

test("should show error message if username and password is empty", async () => {
  const user = userEvent.setup();

  render(<Register />);

  await user.click(screen.getByRole("button", { name: /submit/i }));

  expect(screen.findByTestId("error")).toHaveTextContent(
    "Please enter all fields"
  );
});

jest.congif.js

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

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

/** @type {import('jest').Config} */
const customJestConfig = {
  moduleDirectories: ["node_modules", "src"],
  testEnvironment: "jest-environment-jsdom",
  setupFilesAfterEnv: ["<rootDir>/jest.setup.js"],
};

module.exports = createJestConfig(customJestConfig);

jest.setup.js

import "@testing-library/jest-dom/extend-expect";
import "@testing-library/user-event";

CodePudding user response:

Here you try to find an element with a testid = error. expect(screen.findByTestId("error")).toHaveTextContent("Please enter all fields");

The element you want to get by this statement is <h2 className="text-error">Please enter all fields</h2>

Which does not have a testid. See https://testing-library.com/docs/queries/bytestid/

So do <h2 className="test-error" data-testid="error">Please enter all fields</h2>

To be able to select this element byTestId.

However as you will see in the documentation for byTestId it is not recommended. In this particular case I would suggest getByText. Here is the documentation https://testing-library.com/docs/queries/bytext

And the implementation

expect(screen.getByText("Please enter all fields")).toBeInTheDocument()
  • Related