Testando SSR no Next.js com Jest

Como testar uma página SSR no Next.js usando Jest

LM Luma Montes
2 min read
361 words

Testando SSR no Next.js com Jest

O Jest é uma das ferramentas mais populares para testes no Next.js! Seguindo a documentação oficial, é possível configurar um projeto Next.js com Jest em poucos minutos:

Setting up Jest with Next.js

No entanto, após configurar o projeto, eu me deparei com um problema ao tentar testar uma página que utiliza SSR (Server Side Rendering), utilizando a estrutura de pastas /app do Next.js. Neste post, eu vou mostrar como resolver esse problema.

Eu tenho uma simples página que utiliza SSR para buscar dados de uma API, e renderiza o conteúdo na tela:

async function getData() {
  const res = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/my-endpoint`);
  if (!res.ok) {
    throw new Error("Failed to fetch data");
  }
  return res.json();
}

export default async function Home() {
  const data = await getData();

  return (
    <main>
      <h1>My title</h3>
      <div>
        {data.length === 0 && (
          <p>
           No data available
          </p>
        )}
        {data.map((item: myType, index: number) => (
           // render my data
        ))}
      </div>
    </main>
  );
}

Eu quero testar se o conteúdo é renderizado corretamente, então eu criei um teste para a página:

import { render, screen } from "@testing-library/react";
import Home from "@/app/page";

describe("Home component", () => {
  it("renders correctly with data", async () => {
    render(<Home />);
    expect(screen.getByText("Title")).toBeInTheDocument();
  });
});

No entanto, ao rodar o teste, eu recebo o seguinte erro:

  Error: Uncaught [Error: Objects are not valid as a React child (found: [object Promise]). If you meant to render a collection of children, use an array instead.]

O código acima irá resultar no erro, por conta que o componente Home é renderizado pelo servidor, logo se trata de um componente assíncrono. Por padrão,o Jest não espera a Promise ser resolvida para testar a renderização do componente.

Para resolver esse problema, no momento de testar a renderização do componente Home, eu preciso esperar a Promise ser resolvida. Para isso, eu posso utilizar um await e esperar a renderização do componente:

import { render, screen } from "@testing-library/react";
import Home from "@/app/page";

describe("Home component", () => {
  it("renders correctly with data", async () => {
    const resolvedComponent = await Home();
    render(resolvedComponent);
    expect(screen.getByText("Title")).toBeInTheDocument();
  });
});