Ir para o conteúdo principal

Mock de chamadas de API em testes unitários


Data de elaboração 16/02/2022
Responsável pelo estudo Lucas da Silva Andrade
Equipe do estudo ACDC, Vinicius da Rosa Pereira, Lucas da Silva Andrade, Elias Braga
Alvo Regulariza Já
Origem

o que originou o estudo?

  • Melhoria:  uso de Mocks para testes unitários.
Objetivo Explorar e incentivar o uso de Mocks para testes unitários desenvolvidos em projetos da SETIC
Observações

1. Introdução

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. 

2. Desenvolvimento

2.1. 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. 

2.2. 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. 

image-1645050449414.png

Passo 2. 

image-1645050479651.png

 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. 

image-1645050610116.png

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. 

2.3. 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: 

image-1645050713255.png

 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. 

image-1645050900609.png

 Tendo os parâmetros necessários devidamente mockados, podemos mockar também o próprio serviço do GovDoc e simular o seu comportamento. 

image-1645050928230.png

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”: 

image-1645051002794.png

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: 

image-1645051048365.png

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. 

3. 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.