DEV Community

Cover image for Jest Mock + Reactjs + SVGs
bragamat
bragamat

Posted on

2 1

Jest Mock + Reactjs + SVGs

Quando estamos construindo nossos testes de componentes react, muitas vezes queremos ver como está o nosso DOM e isso pode ficar um pouco desgastante dependendo de quantos elementos estão sendo renderizados! Por exemplo:

import React from "react";
import BirdsSvg from "./BirdsSvg";

function WelcomeMessage({ message }) {
  return (
    <>
      <h1 data-testid="welcome-message">{message}</h1>
      <BirdsSvg />
    </>
  );
}

export default WelcomeMessage;

onde o componente <BirdsSvg /> é um svg.

import React from "react";

export default function BirdsSvg() {
  return (
    <svg
      xmlnsrdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
      xmlns="http://www.w3.org/2000/svg"
      xmlnscc="http://creativecommons.org/ns#"
      xmlnsdc="http://purl.org/dc/elements/1.1/"
      id="svg2"
      viewBox="0 0 332.59 228.16"
      version="1.1"
    >
      <g
        id="layer1"
        transform="translate(-95.351 -259.05)"
        groupmode="layer"
        label="Layer 1"
      >
        <g id="g3798" transform="matrix(3.0193 0 0 3.1136 -192.54 -1017.7)">
          <g
            id="g3954-5-2"
            strokeLinejoin="round"
            fillRule="evenodd"
            transform="matrix(.13195 0 0 .12599 133.41 389.13)"
            stroke="#000"
            strokeLinecap="round"
            strokeWidth="27.39"
          >
            <g
              id="g4720-2-9"
              transform="matrix(.99889 -.047095 .047095 .99889 -22.038 7.2067)"
            >
              <path
                id="path4363-1-21-1"
                rounded="0.56"
                arg1="1.5268686"
                arg2="2.5740661"
                randomized="0"
                cy="342.63394"
                cx="504.21341"
                flatsided="true"
                strokeWidth="46.328"
                fill="#e502b8"
                transform="matrix(-.45011 -.20108 -.24232 .66833 376.47 365.32)"
                transform-center-y="-14.31202"
                transform-center-x="0.79508119"
                type="star"
                sides="3"
                r1="116.27272"
                d="m509.32 458.79c-112.67 4.96-160.3-69.76-108.26-169.81 52.05-100.06 140.57-103.95 201.2-8.85 60.62 95.1 19.73 173.71-92.94 178.66z"
                r2="58.13636"
              />
.
.
.

(pode ver o svg inteiro aqui clicando aqui!)

e nosso teste pro componente <WelcomeMessage />:

import React from "react";
import { render } from "@testing-library/react";
import WelcomeMessage from "../components/WelcomeMessage";

describe("<WelcomeMessage />", () => {
  it("renders message as passed through props", () => {
    const message = "Sintam-se em casa 😁";
    const { getByTestId } = render(<WelcomeMessage message={message} />);

    expect(getByTestId("welcome-message").textContent).toBe(message);
  });
});

Agora supondo que queremos utilizar o helper debug retornado da função render (testing-library/react) pra gente entender como está nosso componente visualmente, esse seria o resultado:

  • o teste ficaria assim:
it("renders message as passed through props", () => {
    const message = "Sintam-se em casa 😁";
    const { debug, getByTestId } = render(<WelcomeMessage message={message} />);

    debug();
    expect(getByTestId("welcome-message").textContent).toBe(message);
  });

e quando rodassemos o comando yarn||npm test o resultado ira se parecer com isso:

Alt Text

Como podem ver, o debug() retorna o DOM naquele momento, incluindo o nosso SVG que ocupa quase toda a tela do terminal e deixa tuo muito bagunçado, o que pode resultar em muitos problemas pra depurar. Só pra vocês terem uma ideia melhor do quão difícil pode ficar pra visualizar tudo, esse é um printscreen do terminal (tirando bastante o zoom e tentando visualizar tudo):
Alt Text

e como vocês podem ver, mesmo assim não foi renderizado 100% do DOM no console.

Então, tendo isso em mente, hoje vou passar pra vocês uma dica bem simples e prática pra ajudar a gente a limpar esse console e a depurar nossos testes: o mock do jest.

o Mock é uma estratégia muito utilizada quando a gente quer testar algo que, dentro de um contexto, tem algum tipo de "contato" com API's externas à nossa aplicação. Porém no contexto de reactjs a gente consegue fazer um mock de um componente.

A estratégia que vamos tomar aqui é fazer um mock para representar nosso svg, ou seja: vamos transformar nosso componente svg em um componente h1 que vai ter um texto dentro... e com isso a gente resolve o problema da bagunça que ficou nosso terminal depois de utilizar a função debug.

Então basta que a gente passe o caminho relativo ao componente svg (que está sendo importado dentro do componente <WelcomeMessage />) e um callback "dizendo" o que a gente quer. Nosso teste vai ficar assim então:

import React from "react";
import { render } from "@testing-library/react";
import WelcomeMessage from "../components/WelcomeMessage";

jest.mock("../components/WelcomeMessage/BirdsSvg", () => () => <h1>Esse é o meu mock</h1>);

describe("<WelcomeMessage />", () => {
  it("renders message as passed through props", () => {
    const message = "Sintam-se em casa 😁";
    const {  debug, getByTestId } = render(<WelcomeMessage message={message} />);
    debug();
    expect(getByTestId("welcome-message").textContent).toBe(message);
  });
});

e agora nosso terminal vai ficar assim:
Alt Text

Como podemos perceber, existe agora um componente "novo" que não existe de verdade no fluxo da nossa aplicação. E podemos fazer ainda mais, retornar null e não renderizar nada relacioado ao componente <BirdsSvg />:

jest.mock("../components/WelcomeMessage/BirdsSvg", () => () => null);

Alt Text

Agora fica muito mais fácil de depurar e fazer alterações nos nossos testes! 😄

O Repositório ta disponível aqui 🚀

Postmark Image

Speedy emails, satisfied customers

Are delayed transactional emails costing you user satisfaction? Postmark delivers your emails almost instantly, keeping your customers happy and connected.

Sign up

Top comments (0)

Postmark Image

Speedy emails, satisfied customers

Are delayed transactional emails costing you user satisfaction? Postmark delivers your emails almost instantly, keeping your customers happy and connected.

Sign up