Introdução aos testes unitários em Go
Tags: go, testing, webdev, programming
Published: 2023-01-13 13:23:56

Os testes unitários são testes que verificam se uma parte específica do código, costumeiramente a nível de função, está funcionando corretamente. Em um ambiente orientado a objetos é usualmente a nível de classes e a mínima unidade de testes inclui construtores e destrutores.

**Por qual motivo devo realizar testes unitários na minha aplicação?**
Mas o verdadeiro propósito do teste unitário é fornecer-lhe feedback quase instantâneo sobre o projeto e a implementação de seu código. A criação de testes unitários, ou melhor, a facilidade ou dificuldade com que você pode criá-los lhe diz exatamente o quão testável é seu código. O quão bem você o projetou.

No nosso exemplo, vamos simular um teste unitário em uma função que faz a validação de um symbol de criptomoedas bem simples mas que foi retirado de produção.
{% embed https://gist.github.com/xxdannilinxx/67039432d6a03fe24d91c26716143d44 %}

Todo o teste unitário necessita de um planejamento prévio. Deve ser de entendimento do desenvolvedor os requisitos que aquela funcionalidade tem que cobrir, qual a sua entrada e qual a sua saída e como se processa o fluxo interno dos dados. Logo, nesse primeiro momento, podemos observar a função e notar que existem dois cenários que não podem faltar, sendo ele o cenário de sucesso e o cenário de falha. Pra isso usaremos a lib mais utilizada que é a [testify.](https://github.com/stretchr/testify)

Na documentação do testify tem alguns exemplos, seguindo os cenários de teste unitário que definimos para nossa função, o código iniciaria parecido com esse.
{% embed https://gist.github.com/xxdannilinxx/dfbc5f0a836c3a9ca54df1db7468aff7 %}

Para testar nosso cenário de falha, basta chamarmos nossa função passando um parâmetro inválido sem a barra e comparar se o erro vindo da função é igual ao erro que definimos para ela.
{% embed https://gist.github.com/xxdannilinxx/86541a53a13a99e5ce6d87a5eb96f13b %}

E no caso do sucesso, basta validarmos que a função não retorne erro, por passar o parâmetro adequadamente.
{% embed https://gist.github.com/xxdannilinxx/a2ea8436e06f5a94e17d6eba238d3ea9 %}

Digite `go test -p 1 -covermode=atomic -tags=unit` para rodar os testes unitários ou use os atalhos do vscode, caso utilize. Você deverá visualizar o retorno com algo parecido a isso:
```
=== RUN   TestValidationSymbol
=== RUN   TestValidationSymbol/Cenário_1_-_Falha
=== RUN   TestValidationSymbol/Cenário_1_-_Sucesso
--- PASS: TestValidationSymbol (0.00s)
    --- PASS: TestValidationSymbol/Cenário_1_-_Falha (0.00s)
    --- PASS: TestValidationSymbol/Cenário_1_-_Sucesso (0.00s)
PASS
ok
```

Claro, essa é só uma introdução, a lib testify tem diversas validações que facilitam a implementação de testes unitários no dia-a-dia, em produção usamos em coisas mais complexas como validar métodos que retornam dados do banco de dados, métodos que fazem validações, métodos responsáveis por gerenciar endpoints e até mesmo com essa lib, conseguimos fazer os testes de integração, que seria um outro assunto.

Lembre-se, sempre que alterar um método ou função, você deve também alterar o teste unitário, pra isso, temos algumas formas de facilitar a checagem dos testes para verificar se teve alguma alteração, criando um atalho no `Makefile` por exemplo e chamando na pipeline do repositório ou até mesmo rodando localmente antes de subir sua branch.

Para rodar o comando do exemplo, basta digitar: `make run-test`
{% embed https://gist.github.com/xxdannilinxx/1f1f0c9e0890d05ac904e43a71137401 %}

É isso. Recomendo a leitura também de artigos sobre criação de mocks, pois muitas das vezes irá precisar de mocks para realizar testes unitários, um exemplo são chamadas de outros serviços, elas precisarão ser feitas via mock.

Até a próxima!