#TesteSemNeura Desmistificando Testes Unitários com Jest
Tags: javascript, tutorial, jest, test
Published: 2023-12-11 13:37:12

Bem-vindo de volta! No último artigo, conversamos sobre a importância dos testes e como eles podem ser um diferencial na nossa jornada como desenvolvedores. Hoje, daremos um passo além e mergulharemos em um aspecto mais prático e aplicado dos testes unitários, focando na ferramenta **Jest**. Se você ainda não leu o artigo anterior eu sugiro a leitura. {% embed https://dev.to/iurynogueira/testesemneura-testes-unitarios-como-comecei-e-como-posso-te-ajudar-267n %}

O Jest é uma das ferramentas mais populares para testes em JavaScript, não apenas simplifica o processo, mas também torna a experiência de escrever testes agradável, você pode usa-lo para testar seus códigos frontend e backend. Está preparado para elevar suas habilidades de teste e deixar o medo de lado? Então, vamos lá!

Antes de começarmos você precisa configurar o jest no seu projeto, para isso é só chamar nosso velho amigo npm, execute o comando na raiz do seu projeto.

```bash
npm install --save-dev jest
```
ou execute com o Yarn:

```bash
yarn add --dev jest
```

Particularmente eu gosto sempre de adicionar um novo script ao meu package.json para executar os testes, dessa forma:

```json
"scripts": {
  "test": "jest"
}
```

Agora é só executar **npm run test** ou **yarn test**.

Vamos pegar um caso bem didático para nosso primeiro teste, quero que você se atente principalmente a estrutura do teste, eu costumo escrever testes pensando sempre na seguinte ordem: O que meu teste tem que validar, preparação/processamento e o que eu espero que seja correto na saída do processamento. Vou deixar mais claro com o exemplo abaixo:

```js
// primeiro.test.js

test('dois mais dois é igual a quatro', () => {
  expect(2 + 2).toBe(4);
});
```

para executar esse teste execute:

```bash
npm test
```

ou execute com o Yarn:
```bash
yarn test
```

você verá essa saída no terminal indicando que seu teste passou.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hrqm4lbysql478rfg22v.png)


note que eu procuro validar que "dois mais dois é igual a quatro", e eu espero (expect) que o resultado do processamento dessa soma seja 4 (toBe(4)). Por enquanto vamos nos atentar nisso, na estrutura de teste, o que se deve testar e o que esperar de cada teste, esse conceito é muito importante.

Vamos supor que você tenha uma função que deve recebe um valor em real (nossa moeda) e converte esse valor para dólar considerando que o dólar custa 5 reais. Vamos lá!

```js
// conversorRealParaDolar.test.js

// Função que converte um valor de reais para dólar
function converterRealParaDolar(valor) {
  const valorDolar = 0.2;

  const valorConvertido = valor * valorDolar;
  return Number(valorConvertido.toFixed(2));
}

test('100 reais deve ser 20 dólares', () => {
  expect(converterRealParaDolar(100)).toBe(20);
});

test('deve lançar um erro para valores negativos', () => {
  expect(() => converterRealParaDolar(-100)).toThrow(
   'O valor a ser convertido deve ser um número positivo.'
  );
});
```

Note que eu chamo nossa função que converte e retorna o valor em dólar, mais uma vez checo o resultado com o toBe(), também adicionei um caso que um bom QA testaria, um número negativo! Nesses casos utilizamos o **toThrow** para checar uma exception, sempre é importante cobrir todos os casos possíveis de entrada para sua função e mapear os casos no teste, você pode escrever mais de um caso de **test** para uma mesma funcionalidade. Agora execute os testes com o comando que já falei anteriormente, você verá o seguinte resultado:


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vzh6g8kvw9c7qlthw3an.png)

O segundo caso de teste quebrou pois nossa função não lança um erro quando um número é negativo, "mas Iury, é claro que o teste vai quebrar, como tu tá testando uma coisa que não foi implementada?" Isso é o que a gente chama de TDD! Basicamente você implementa todos os casos de teste e o desafio é você ir tirando o "vermelho" dos seus testes quando for implementando a função, mas isso é assunto para outro artigo, vamos seguir somente com esse breve conceito, um "ifzinho" no nosso código resolverá esse problema.

```js
// funcao atualizada
function converterRealParaDolar(valor) {
    const valorDolar = 0.2;

    // chique né?
    if (isNaN(valor) || valor <= 0) {
      throw new Error('O valor a ser convertido deve ser um número positivo.');
    }

    const valorConvertido = valor * valorDolar;
    return Number(valorConvertido.toFixed(2));
  }
```

execute os testes novamente e veja que nosso teste passou, não é satisfatório? :)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rz6m4jy207x8z63lp72i.png)

O **expect** possui vários **matchers**, o mais comum como já usamos aqui é o **toBe**, outro muito comum de se usar no dia a dia é o **toHaveLength** onde você pode checar o tamanho de um array ou de uma string como no exemplo abaixo (repare também no not :D):

```js
expect([1, 2, 3]).toHaveLength(3);
expect('abc').toHaveLength(3);
expect('').not.toHaveLength(5);
```

para conferir todos os _matchers_ sugiro que você consulte a [doc](https://jestjs.io/docs/expect#matchers)

Outro aspecto fundamental nos testes unitários é a cobertura de código, no exemplo da função de conveterRealParaDoar ela está 100% coberta porque nossos testes passam por todas as linhas de código, caso o teste da exception fosse removido nós não teríamos todo nossa função validada, por isso é importante sempre manter essa cobertura alta para que tenhamos o número máximo de casos possíveis mapeados em nossos testes, isso vai te ajudar a não ter aquele medo que falamos no primeiro artigo e você vai se sentir mais a vontade para realizar mudanças no código, agora vamos configurar a coleta do coverage!

1. Abra o arquivo de configuração do Jest (normalmente **jest.config.js** ou no bloco jest em seu **package.json**).

2. Adicione essa configuração para habilitar a geração de cobertura:

```js
// jest.config.js

module.exports = {
  collectCoverage: true,
  collectCoverageFrom: ['src/**/*.js'], // esse é o caminho dos seus testes,
  coverageReporters: ['json', 'lcov', 'text', 'html'], // eu gosto de adicionar o HTML porque ele cria uma página bonitinha com vários progress.
};
```

3. Só executar!

```bash
npm test --coverage
```
ou execute com o Yarn:

```bash
yarn test --coverage
```

Acredito que com isso nós temos nossa porta de entrada para os testes, aconselho praticar com suas funções diariamente, no próximo artigo eu vou abordar sobre TDD!

Agradeço por sua leitura até aqui e gostaria muito do seu feedback, estou comprometido para melhorar e fornecer um conteúdo útil para ajudar no desenvolvimento de vários outros devs por ai a fora. Obrigado!