menu

SHARKLABS

Testes Unitários com Node.js, Jest e TypeScript

/
/
Testes Unitários com Node.js, Jest e TypeScript
bookmark Node.js, Testes, TypeScript access_time

Tutorial de Testes com Jest e TypeScript em Node.js

O objetivo deste tutorial é mostrar como executar testes unitários com Jest e TypeScript de forma objetiva, clara e direta ao ponto. Então vamos ao que interessa.

Instalação

Primeiramente você instala o TypeScript:

npm install typescript --save-dev

Agora você pode instalar o Jest:

npm install jest --save-dev

Por fim você precisa instalar o pacote ts-jest e outro pacote com os tipos do Jest:

npm install ts-jest --save-dev
npm install @types/jest --save-dev

Configuração

Antes de iniciar os testes você precisar configurar o preset. No Jest o preset é um conjunto de configurações que servem de base.

Embora essas configurações sejam muito simples, o ts-jest disponibiliza um comando para criar o arquivo jest.config.js com o preset correto.

npx ts-jest config:init

Para mais detalhes sobre as configurações do Jest veja estes links:

Executando Testes com Jest e TypeScript

Por padrão o Jest executa todos os arquivos que ficam na pasta __tests__ ou que tenham os trechos "test" ou "spec" no nome do arquivo.

Digamos que você tenha o arquivo "/src/index.ts":

export function double(x: number): number {
  return x * 2;
}

export function concat(...args: string[]): string {
  return args.reduce((result, param) => result + param, '');
}

Para testar essas funções basta você criar o arquivo "__tests__/index.test.ts":

import { double, concat } from '../src/index';

describe('testing index file', () => {
  test('double function', () => {
    expect(double(5)).toBe(10);
  });

  test('concat function', () => {
    expect(concat('Paul', ' ', 'McCartney')).toBe('Paul McCartney');
  });
});

Este exemplo contém um grupo de testes definido pela função describe e dentro do grupo tem dois testes definidos com a função test. Lembrando que também é possível criar sub-grupos com a função describe.

Dentro da função test você precisa declarar uma expectativa seguida de um "matcher". Neste exemplo, expect é a expectativa e toBe é o matcher. Ou seja, você espera que o retorno de uma função (ou uma varíavel) seja igual a um determinado valor.

Para realizar os testes, execute este comando:

npx jest

Pronto! Agora se algum teste falhar o Jest vai mostrar uma mensagem de erro. Como estamos utilizando Jest e TypeScript, vale destacar que inconsistências de tipos também serão apresentadas.

Aperfeiçoando seus Testes

O exemplo que mostrei é algo muito simples, mas conforme seu software cresce seus testes também crescerão e provavelmente você precisará de funcionalidades mais avançadas.

O matcher mais comum é o toBe e que funciona muito bem para comparar valores primitivos, porém com o tempo você precisará de matchers mais avançados. Eu fiz uma lista com os matchers mais populares:

  • toEqual: Útil para verificar objetos e suas propriedades
  • toBeFalsy: Útil para verificar valores que podem ser convertidos para false por meio da coerção do JavaScript.
  • toBeTruthy: Útil para verificar valores que podem ser convertidos para true por meio da coerção do JavaScript.
  • toContain: Útil para verificar arrays com valores primitivos.
  • toContainEqual: Útil para verificar arrays com objetos.
  • toMatch: Útil para verificar strings e expressões regulares.
  • toThrow: Útil para verificar se uma função lançou uma exceção.

Algo muito interessante sobre os matchers, é que se você usar o prefixo .not a condição será invertida. Por exemplo:

expect(1).not.toBe(2);

Se você deseja ver todos os matchers, clique aqui para acessar a documentação oficial.

Testes Assíncronos com Promises

Algo muito comum em JavaScript é testar funções assícronas. Por exemplo, digamos que você tenha a seguinte função:

export function waitSeconds(seconds: number): Promise<string> {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(`waited ${seconds} seconds`);
    }, seconds * 1000);
  });
}

Basicamente essa é uma função que aguarda alguns segundos e retorna uma mensagem. Ela tem como parâmetro um número que represente a quantidade de segundos e retorna uma Promise<string>.

Você pode testar isso de várias maneiras, mas eu separei quatro tipos de testes para esta função:

import { waitSeconds } from '../src/index';

describe('example of asynchronous testing', () => {
  test('testing with async/await', async () => {
    expect(await waitSeconds(1)).toBe('waited 1 seconds');
  });

  test('testing returning a promise', () => {
    return expect(waitSeconds(1.5)).resolves.toBe('waited 1.5 seconds');
  });

  test('testing returning a promise with callback function', () => {
    return waitSeconds(0.5).then((response) => {
      expect(response).toBe('waited 0.5 seconds');
    });
  });

  test('testing with callback function', (done) => {
    waitSeconds(0.8).then((response) => {
      expect(response).toBe('waited 0.8 seconds');
      done();
    });
  });
});

Vale destacar que embora sejam quatro tipos diferentes de testes, o resultado deles é o mesmo e você pode escolher o que for mais conveniente para seu caso. Vou deixar aqui o link da documentação oficial sobre testes assíncronos.

Vou deixar aqui também as versões das bibliotecas utilizadas:

  • jest: 26.1
  • typescript: 4.0

Dúvidas ou sugestões é só entrar em contato. Abraço.

Autor
"Any fool can write code that a computer can understand. Good programmers write code that humans can understand." Martin Fowler