Testando componentes com Testing Library
Testar 'como o componente foi implementado' quebra a cada refatoração; testar o que o usuário vê e faz não.
Um erro comum ao testar componente é testar detalhe de implementação — acessar estado interno, checar se uma função específica foi chamada por dentro. Esse tipo de teste quebra toda vez que você refatora o componente, mesmo sem mudar nada do que o usuário vê. Testing Library evita isso de propósito: ela só te dá acesso ao que aparece na tela e ao que o usuário consegue fazer.
O que testar
Em vez de "a função handleSubmit foi chamada", teste comportamento visível: "quando eu clico em Salvar com os campos preenchidos, a mensagem de sucesso aparece na tela". Se você conseguir reescrever o componente inteiro por dentro e o teste continuar passando sem mudar uma linha, o teste está no nível certo.
render, screen e userEvent
import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { LoginForm } from "./login-form";
test("mostra erro quando o e-mail é inválido", async () => {
render(<LoginForm />);
const user = userEvent.setup();
await user.type(screen.getByLabelText("E-mail"), "nao-e-um-email");
await user.click(screen.getByRole("button", { name: "Entrar" }));
expect(await screen.findByText("E-mail inválido")).toBeInTheDocument();
});render monta o componente num DOM virtual; screen é onde você busca elementos — getByRole, getByLabelText — sempre preferindo a forma como um usuário real encontraria aquele elemento (por texto do botão, por label do campo), não por um seletor de CSS interno. userEvent simula interação real: digitar, clicar, disparando os mesmos eventos que uma interação de verdade dispararia.
Um exemplo completo
import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { ContadorDeLikes } from "./contador-de-likes";
test("incrementa o contador ao clicar", async () => {
render(<ContadorDeLikes inicial={3} />);
const user = userEvent.setup();
expect(screen.getByText("❤ 3")).toBeInTheDocument();
await user.click(screen.getByRole("button"));
expect(screen.getByText("❤ 4")).toBeInTheDocument();
});Repare que o teste não sabe (nem precisa saber) que existe um useState por trás — ele só sabe que, depois do clique, o texto na tela mudou de ❤ 3 pra ❤ 4.
Exercício
Escreva um teste pro componente ContadorDeLikes (da lição de Server vs. Client Components) que verifica que ele começa mostrando o valor de inicial, sem clicar em nada ainda.