Jest, Babel e TypeScript: Configurando testes para seu projeto
Tags: ptbr, webdev, javascript, testing
Published: 2020-02-10 06:25:43

---
title: Jest, Babel e TypeScript: Configurando testes para seu projeto
published: true
description: Configurando Jest com Babel e TypeScript
tags: ptbr, webdev, javascript, testing
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/khqubbta6kb7jwxk70rj.png
---

Devido a grande quantidade de ferramentas e configurações, fica difícil entender o "como" e achar exemplos de "onde" devemos configurar nossas ferramentas de desenvolvimento web.

Nesse eterna evolução da nossa área, vamos focar em três ferramentas principais que você pode encontrar hoje em dia: **Jest**, **Babel** e **TypeScript**.

Vamos focar em 2 categorias aqui:

- Um projeto com Babel e adicionando TypeScript, onde teremos testes em JavaScript e TypeScript
- Um projeto TypeScript, onde teremos testes em TypeScript

Vamos começar pelo projeto de TypeScript.

# Jest e TypeScript

A um tempo atrás, eu escrevi um artigo de como rodar testes em [Node.js com TypeScript](https://medium.com/@oieduardorabelo/node-js-e-typescript-o-como-e-com-testes-7affce2c02a8), o princípio é o mesmo! Como esse projeto contém apenas TypeScript, não precisamos ir muito além nas ferramentas extras.

Vamos adicionar TypeScript e Jest:

```bash
mkdir jest-typescript

cd $_

npm init -y

npm install --save-dev \
    jest@25.1.0 \
    typescript@3.7.5

npm install --save-dev \
    ts-jest@25.2.0 \ 
    @types/jest@25.1.2
```

- Instalamos as versões atuais de Jest e TypeScript
- Com [ts-jest](https://github.com/kulshekhar/ts-jest), teremos suporte a source map e type checking ao rodar nossos testes
- E instalamos o `@types/jest@25.1.2` para termos os tipos de definição do Jest, tais como `expect`, `test`, `it` etc

Outra funcionalidade bacana do [ts-jest](https://github.com/kulshekhar/ts-jest) é sua CLI para criar uma configuração inicial:

```bash
npx ts-jest config:init
```

Com isso, teremos um `jest.config.js` na nossa pasta da seguinte forma:

```tsx
module.exports = {
  preset: 'ts-jest',
  testEnvironment: 'node',
};
```

[Você pode alterar `testEnvironment` para `jsdom`](https://jestjs.io/docs/en/configuration#testenvironment-string).

Fazemos o mesmo para o TypeScript:

```bash
npx tsc --init
```

E teremos nosso `tsconfig.js`:

```json
{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",

    "strict": true,

    "esModuleInterop": true,

    "forceConsistentCasingInFileNames": true
  }
}
```

**Nota:** Não há nenhuma personalização nessa configuração do TypeScript. Eu apenas removi os comentários.

Agora, podemos criar nosso arquivo de teste:

```bash
cat hello.test.ts
```

E atualizar o **package.json**:

```json
	...
  "scripts": {
    "test": "jest --no-cache"
  }
  ...
```

Escrevemos nosso teste em `hello.test.ts`:

```tsx
interface Hello {
  name: string
}

let me : Hello = {
  name: 'me'
}

it('works', () => {
  expect(me.name).toBe('me');
})
```

E teremos um resultado como:

```bash
> /jest-typescript
> jest --no-cache

 PASS  ./hello.test.ts
  ✓ works (2ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        1.481s
Ran all test suites.
```

Agora, podemos focar na integração do Babel com TypeScript.

# Jest, Babel e TypeScript

Para esse exemplo, iremos criar uma nova pasta `jest-babel-typescript` e instalarmos nossas dependências:

```bash
mkdir jest-babel-typescript
cd $_

npm init -y

npm install --save-dev \
	jest@25.1.0 \
	babel-jest@25.1.0 \
	@babel/core@7.8.4 \
	@babel/preset-env@7.8.4 \
	
npm install --save-dev \
	@babel/preset-typescript@7.8.3 \
	@types/jest@25.1.2
```

- Instalamos as versões atuais de Jest e Babel
- E por último, instalamos o `@babel/preset-typescript`, permitindo que o Babel entenda a sintaxe TypeScript. Você leu certo, não precisamos instalar o pacote TypeScript `typescript@*`.
- O `@types/jest@25.1.2` para termos os tipos de definição do Jest, tais como `expect`, `test`, `it` etc

Como mencionado acima, não precisamos instalar o TypeScript `typescript@*`, pois o Babel com `@babel/preset-typescript` entende a sintaxe TypeScript. O que NÃO ACONTECE AQUI é o type checking, pois o preset simplesmente converte a sintaxe TypeScript para JavaScript.

Se você quiser utilizar o type checking, você precisa instalar o TypeScript `typescript@*` e ter um comando como `"typecheck": "tsc --noEmit"` em seu `package.json`, com um arquivo `tsconfig.json` em sua pasta.

Iremos criar 4 arquivos:

- **multi.js** e **multi.test.ts**: Nosso código em um arquivo JavaScript e seu teste em um arquivo TypeScript
- **sum.ts** e **sum.test.js**: Nosso código em um arquivo TypeScript e seu teste em um arquivo JavaScript

No **multi.js**:

```js
export function multi(a, b) {
  return a * b;
}
```

E em **multi.test.ts**:

```ts
import { multi } from "./multi";

test("1 * 2", () => {
  expect(multi(1, 2)).toBe(2);
});
```

Em **sum.ts**:

```ts
export function sum(a: number, b: number): number {
  return a + b;
}
```

E em **sum.test.js**:

```js
import { sum } from "./sum";

test("1 + 2", () => {
  expect(sum(1, 2)).toBe(3);
});
```

Atualizamos nosso **package.json**:

```json
	...
  "scripts": {
    "test": "jest --no-cache"
  }
  ...
```

E teremos um resultado como:

```bash
> @ test /jest-babel-typescript
> jest --no-cache

 PASS  ./multi.test.ts
 PASS  ./sum.test.js

Test Suites: 2 passed, 2 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        1.816s
Ran all test suites.
```

# Finalizando

Apesar do exemplo acima não conter configurações complexas, como *path alias* (e.g. `import P from '@services/api'`) ou webpack, a mensagem é de que é possível integrar todas essas opções.

Podemos desenhar 2 cenários aqui:

**1. Eu tenho um projeto em Babel e quero MIGRAR para TypeScript.**

Coloque o `@babel/preset-typescript` no seu projeto e todos os `@types/` que você precisar, isso será necessário para fazer o Babel entender a sintaxe TypeScript e incluir definições das suas dependências. Migre sua base de código para `*.ts(x)`. 

No final, faça a instalação do `typescript@*` e use `tsc --init` para criar uma configuração base. Remova o Babel e suas configurações e utilize `tsc` como novo compilador.

**2. Eu tenho um projeto em Babel mas quero TYPE CHECKING do TypeScript**

Coloque o `@babel/preset-typescript` no seu projeto e todos os `@types/` que você precisar, isso será necessário para fazer o Babel entender a sintaxe TypeScript e incluir definições das suas dependências. 

Faça a instalação do `typescript@*`, e tenha um `tsconfig.json` com `"noEmit": true` e `"allowJs": true`, utilize o comando `tsc` para fazer o type checking. 

**Nota:** O `tsconfig.json` pode ser necessário no caso 1 e 2 desde o começo, caso você tenha *path alias* em Babel, você também precisa criar *path alias* para o TypeScript.

Cada projeto de um objetivo diferente, mas isso não quer dizer que não podemos configurar as mesmas ferramentas de base.

Quer compartilhar algo ou deixar uma pergunta? Use os comentários! 👋

Tenha umm bom código! 🥳