Mock de chamadas de API em testes unitários
Data: 19/09/22
Autores:
- Vinicius da Rosa Pereira
- Lucas da Silva Andrade
1. Objetivo
Explorar e incentivar o uso de Mocks para testes unitários desenvolvidos em projetos da SETIC
2. Justificativa
Sabemos a importância dos testes, principalmente quando trabalhamos com TDD, por isso é tão importante estar sempre atualizados quando o assunto é teste. Foi observado que em determinados projetos, as chamadas de serviços e APIs são testadas por completo, precisando de dados reais e resultando em quebras por conta disso.
3. Desen
O que é mock?
Mock refere-se à utilização de dados fictícios, baseados em nosso modelo de negócio para verificar o comportamento de nossas aplicações, sendo utilizado para emular objetos individuais, serviços ou até repositórios.
Instalação
Para o desenvolvimento, utilizamos do framework Moq, podendo ser adicionado a qualquer projeto .NET.
Sua instalação pode ser pela interface:
Passo 1.
Passo 2.
Ou utilizando linha de comando, através do Package Manager Console:
Install-Package Moq -project <Nome_do_projeto>
Implementação
Temos na imagem abaixo um exemplo de um teste unitário em um cenário em que temos uma classe que verifica o preço de um produto e a sua interface.
Na linha 8 é criada uma instância mockada da interface, ou seja, uma instância fictícia. Já na linha 9, fazendo o setup da instância mockada, podemos definir o comportamento dela, e definir o que ela deve retornar.
Exemplos reais
Para um melhor entendimento, traremos uma dor real para os projetos da SETIC. Tomaremos como exemplo a API do GovDoc, que é utilizado por grande parte dos projetos da SETIC.
Em diversos serviços precisaremos chamar algum dos endpoints do GovDoc, então para testar esses serviços, ao invés de chamar a API real, nós precisamos simular ela, aí que entra o mock.
Veja o exemplo de um Serviço do GovDoc:
Nós precisamos mockar esse serviço para realizar o teste da disponibilização de um bloco de assinatura, mas o próprio serviço do GovDoc também recebe como parâmetro, duas interfaces para seu funcionamento.
A saída é mockar cada um dos elementos necessários para o teste da nossa funcionalidade.
Tendo os parâmetros necessários devidamente mockados, podemos mockar também o próprio serviço do GovDoc e simular o seu comportamento.
Para cada um dos testes envolvendo a API, será necessária a configuração do mock, parece complexo e com muito retrabalho, mas pode ser simplificado.
Usaremos para o próximo exemplo, a API do Sauron, também utilizada majoritariamente nos projetos da SETIC.
Para o próximo exemplo, utilizamos uma classe para ajudar na montagem dos testes, chamamos essa classe de “Faker”. Para todos os testes unitários que utilizarão de algum serviço do sauron, delegamos a montagem do mock para um método da classe “Faker”:
Na implementação mostrada, mockamos todos os parâmetros necessários para o serviço do Sauron, e passamos no construtor o mock.object, que é o objeto mockado.
Mas para o retorno do método, não passaremos o sauronServicosMock.Object, pois precisamos recuperar o próprio mock, para fazermos as preparações específicas para cada teste, como no bloco de código a seguir:
Notamos que por retornar um Mock<SauronServicos> pela classe Faker, podemos passar no parâmetro do serviço RemoverResponsavel o seu .Object, e ainda fazer o setup do método desejado.
4. Conclusão
Com isso podemos verificar que o Mock é um excelente recurso, sendo muito útil para situações que envolvem injeção de dependências, facilitando o teste de interfaces com dados fictícios.