Testando seu client Dio com MockWebServer em Flutter

Tiago Geanezini
gb.tech
Published in
4 min readSep 15, 2020

Quando se fala em desenvolver aplicações pensando em melhoria contínua e escalabilidade, é muito difícil, para não dizer impossível, não falar da criação de testes automatizados. Com eles fica mais fácil validar os reais impactos que uma mudança de escopo ou de implementação podem gerar no projeto como um todo, ou em uma parte específica dele. Sua importância é indiscutível na hora de garantir a qualidade da aplicação que está sendo desenvolvida, seja ela mobile, front-end ou back-end.

Os testes normalmente são divididos levando em conta a relação custo x quantidade e essa relação é normalmente representada no formato de pirâmide, com os testes mais rápidos de serem desenvolvidos (testes unitários) aparecendo na parte inferior da pirâmide e os testes mais custosos de serem desenvolvidos, levando em conta tempo e complexidade de desenvolvimento (testes end-to-end), aparecendo no topo. Existem diversas formas diferentes de apresentação dessa pirâmide, mas uma das mais comuns é a que está representada abaixo.

Pirâmide de testes. Fonte: The Test Pyramid in Practice

O foco desse artigo está nos testes de integração, que têm por objetivo, como o nome sugere, validar que diferentes partes da aplicação se comunicam bem quando colocadas juntas, e isso vale também para chamadas à API. E o que pode ser melhor do que testar essa comunicação num "servidor de verdade"? É aí que entra o MockWebServer.

Mas o que é o MockWebServer?

O MockWebServer é uma lib que busca facilitar os testes de integração ao criar um servidor independente e flexível durante a execução dos testes, que irá responder a um script pré-determinado ou encaminhar uma requisição para um dispatcher. Esse servidor pode responder em uma porta específica (ex.: 8081) ou numa porta efêmera, escolhida pelo próprio SO. Essa configuração é feita ao criar uma nova instância do MockWebServer da seguinte maneira:

Uma vez criado, para inicializar o servidor basta executar o comando server.start() durante o passo de setUp dos testes.

É preciso encerrar o servidor durante o tearDown dos seus testes. Para isso, basta chamar a função server.shutdown().

E como o MockWebServer funciona?

Vamos a um exemplo prático, testando um serviço que retorna informações de um usuário ao receber um id na requisição. Primeiramente, adicione a lib como uma dependência de desenvolvimento no seu pubspec.yaml

dev_dependencies:
mock_web_server: ^4.1.1

Uma das vantagens de usar o MockWebServer é a possibilidade de simular diferentes resultados para a requisição que será realizada. No exemplo abaixo, esperamos que a requisição retorne com status 200 e que o objeto retornado no body da resposta seja o User declarado acima em formato JSON.

Em seguida, disparamos a requisição para o client e fazemos com que o MockWebServer capture a mesma com o método takeRequest.

Após disparar e armazenar a request realizada é possível realizar os asserts e validar se o que era esperado no teste foi mesmo recebido pela aplicação.

O código completo do teste pode ser visualizado abaixo.

Quais outros recursos o MockWebServer oferece?

O exemplo acima mostra de maneira simples como utilizar o MockWebServer para realizar os testes em um client do Dio, mas ele pode ser usado para testar todos os tipos de client HTTP, Data Providers e afins. Outras funcionalidades apresentadas pela lib são a possibilidade de adicionar um delay nas respostas para validar cenários de timeout das chamadas, utilizar IPv6 e também TLS (Test Layer Security) na criação do server, esses dois últimos podem ser utilizados ao passar parâmetros específicos no construtor durante a criação da instância do MockWebServer.

Conclusão

Ter a possibilidade de testar uma integração com API utilizando um servidor real que roda localmente na sua máquina é extremamente vantajoso quando se busca garantir a qualidade do que foi desenvolvido. E as vantagens oferecidas pelo MockWebService são excepcionais no auxílio da escrita desses testes de integração, como, por exemplo, a possibilidade de utilizar diversos clients diferentes, testar cenários de timeout, utilização de IPv6, entre outras. Além de ser uma biblioteca de fácil implementação, é uma ferramenta poderosa na hora de garantir a qualidade da aplicação sendo desenvolvida. Com uma boa documentação e bons exemplos práticos na página do seu repositório, essa lib é uma recomendação fácil para quem está buscando mais uma alternativa de garantir que a comunicação com a API do seu projeto Flutter está funcionando como deveria.

--

--