# Testes Unitários
Testes unitários são a forma de destar cadas aspecto do código isolado, pra isso ser possivel devemos pensar em 3 aspectos em especifico.
1. Todas as dependencias relacionadas ao código devem ser isoladas.
2. Testar a menor unidade possivel, isso significa que se uma função tem mais de uma exessão, teste isoladamente cada uma.
3. o importante é testar o resultado palpavel, e qual a lógica a ser aplicada, não deixe seus mocks mascararem o resultado esperado.
## Organização
Testes unitários podem ser organizados de duas formas em especifico, sendo que cada uma pode ser aplicada.
__Por sub-extensão__
A primeira é criar um arquivo com o mesmo nome do componente adicionanso o sulfixo `.test` antes da extensão. Exemplo
```
|->Button
|-->Button.test.js
|-->index.js
```
__Por diretório__
Quando temos muitos arquivos derivados de um componente, criar varios `.test` pode causar problemas de visibilidade, então neste caso faz mais sentido isolar todos os testes em um diretório
`__test__` dentro do escopo da funcionalidade testada, é bom manter a subextension para funçoes do editor como uma bosca rápida e qualificação da extensão sejam evidentes, mas não devemos colocar nenhum outro arquivo alem de testes nesse diretório.
```
|--> Button
|--> index.js
|-->BtnContainer.js
|-->BtnFile.js
|-->BtnSubmit.js
|-->__tests__
|-->BtnContainer.test.js
|-->BtnFile.test.js
|-->BtnSubmit.test.js
```
## Mocks de dados
Dados estáticos e funçoes de ordem maior usadas para substituir comportamentos de extensoes terceiras, podem ser isoladas de forma mais dinamica, quando um mock isolado e pequeno este pode ser declarado dentro do proprio teste, já quando temos uma boa variedade faz mais sentido isolarmos por sub-extensão com o sufixo `.mock` ex: `Button.mock.js`. Podemos ainda pensar no caso e
A função dos testes unitários é testar as partes de um módulo, em isolamento. Se tivermos uma biblioteca de máscaras de texto, seriam testes que verificam que as máscaras funcionam como esperado. Esses testes costumam ser rápidos de escrever, mudam pouco (somente quando o módulo sofre refatorações), custam pouco tempo de máquina e oferecem um grau de confiabilidade no núcleo do aplicativo.
## Organização interna
Dentro dos testes para cada exceção possível criamos um bloco de testes que pode utilizar a função `test()`, mas esses blocos muitas vezes utilizan spies, stubs ou mocks(declarações compartilhadas entre multiplos casos de teste) declarados mais de uma vez, por esta razão agrupamos, em um block `describe()`, onde fazemos a declaração uma unica vez e caso necessite ter algum `reset` de algum recurso podemos aplicar isto antes da execução de cada função.
Exemplos:
```
// React component Button
import React from "react";
import { fireEvent, render } from "@testing-library/react";
// bloco describe agrupa multiplos testes
describe('Button Component', () => {
const callback = jest.fn();
// beforeEach é uma das funçoes que podem ser executadas como helper
beforeEach(() => {
callback.mockClear();
})
test("should render and be clickable", () => {
const { getByText, container } = render(
<Button onClick={callback}>{sampleText}</Button>
);
expect(callback).not.toHaveBeenCalled();
fireEvent.click(getByText(sampleText));
expect(callback).toHaveBeenCalled();
});
test("should render and not be clickable", () => {
const { getByText, container } = render(
<Button onClick={callback} disabled>{sampleText}</Button>
);
expect(callback).not.toHaveBeenCalled();
fireEvent.click(getByText(sampleText));
expect(callback).not.toHaveBeenCalled();
});
})
});
```
## Padrões de messages
Os textos dentro das funçoes `describe` e `test` tem como função a identificação e busca, dado isto é adequado aplicarmos alguns padrões que podem ser de utilidade dentro de suites de testes.
- __Messages em describes:__ dentro das funções describe a message tem por finalidade informar qual a funcionalidade que será testada naquela coleção e como podemos qualificala com um sulfixo.
- Toda funcionalidade em um describe pode ser qualificada como `Component`, `Function`, `Class` ou `Method`.
- exemplos:
- `describe('Button Component', () => {})`
- `describe('setInputMask Function', () => {})`
- `describe('Transaction Class', () => {})`
- `describe('setTransferCode Method', () => {})`
- __Messages em test:__ os blocos `test()` utilizam as messages para descrever o resultado esperado para aquele caso.
- exemplos:
- `test('should return only odd numbers', () => {})`
- `test('should set a new value in transtion attribute', () => {})`
## Tips and Tricks
1) funções assincronas precisam de um callback assyncrono na execução do `describe e test`.
2) existem varios helpers como beforeEach, afterEach, beforeAll que podem ser uteis durante os testes.
3) podemos mockar valores no momento da importação, assim como interceptar valores globais.
4) As funçoes `describe` e `test` são objetos que possuem diversos metodos estáticos uteis como `test.each()`, pra quando precisamos testar coleções.