Jest Mock + Reactjs + SVGs
Tags: react, jest, mock, testing
Published: 2020-08-08 14:54:56

  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:

```javascript
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. 
```javascript
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!](https://gist.github.com/bragamat/898a6784ba6f0881619feb4a27da733d))

e nosso teste pro componente `<WelcomeMessage />`: 
```javascript
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](https://testing-library.com/docs/react-testing-library/intro)) pra gente entender como está nosso componente visualmente, esse seria o resultado:
* o teste ficaria assim:
```javascript
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](https://dev-to-uploads.s3.amazonaws.com/i/547uwv4ihrmr9qq97dbs.png)

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](https://dev-to-uploads.s3.amazonaws.com/i/fla2kgxafbqqxia2zwm4.png)

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](https://jestjs.io/).

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:
```javascript
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](https://dev-to-uploads.s3.amazonaws.com/i/k9ntcx56i4nucn2t63zy.png)

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 />`:
```javascript
jest.mock("../components/WelcomeMessage/BirdsSvg", () => () => null);
```

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/cqg10fmv1mai3issd94z.png)

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

O Repositório ta disponível [aqui](https://github.com/bragamat/jest-mock-react-svg) :rocket: