Utilizando gRPC Wiremock para mockar respostas gRPC em testes integrados

Tony Augusto
4 min readOct 28, 2021

--

Mockar respostas de API’s definitivamente não é algo novo e temos várias ferramentas que conseguem fazer isso de forma eficiente há muito tempo. No entanto, volta e meia acabamos nos deparando com alguns cenários, protocolos ou frameworks que podem complicar até a mais trivial das tarefas. Neste artigo gostaria de explicar sobre o gRPC Wiremock, uma ferramenta capaz de mockar respostas de serviços que se comunicam via gRPC.

Cenário

Antes de mais nada, segue um exemplo do cenário de teste que será abordado neste artigo. Lembrando que não entrarei em detalhes de implementação do código em si e sim sobre a configuração do grpc-wiremock. De qualquer forma, basta acessar este repositório para ter um exemplo de código mais detalhado.

Cenário dos testes

Passo 1: Criando um docker-compose para o serviço

Para o nosso exemplo usarei uma imagem docker do gRPC Wiremock. As configurações necessárias são mínimas e portanto não há necessidade de detalhamento. O nosso docker-compose será basicamente assim:

Bem simples, não?

Nos volumes os diretórios ./wiremock/protos e ./wiremock/stubs são importantes para nós e logo falaremos sobre eles.

Passo 2: Copiando o arquivo .proto dos serviços

Para que o gRPC Wiremock consiga criar os mocks é necessário o contrato (arquivo .proto) de comunicação entre os serviços. No nosso exemplo, suponha que temos um serviço chamado shopping-cart-service que tenha um contrato .proto de comunicação com o serviço payment-service. Algo como isso aqui:

Agora devemos adicionar uma cópia deste contrato a um diretório que o grpc-wiremock tenha acesso, no nosso caso é o ./wiremock/protos que definimos no volume do docker compose. Feito isso, agora vamos definir as request e response que deverão ser mockadas.

Passo 3: Criando os stubs de requisição e resposta

Neste ponto do artigo nós já temos o docker compose para executar o serviço do grpc wiremock local e o contrato .proto de comunicação entre os serviços shopping-cart e payment, o que nos resta é definir o formato da requisição e as respostas que deverão ser fornecidas pelo grpc-wiremock.

Devemos agora definir em um arquivo JSON qual requisição e resposta deve ser servida pelo nosso mock. Para isso, vamos criar um arquivo JSON chamado response-ok.json dentro do diretório ./wiremock/stubs/mappings o nome mappings é usado internamente pelo serviço do grpc-wiremock, então o diretório precisa estar nomeado assim, mas nada impede que você crie, dentro do /mappings, subdiretórios para organizar seus arquivos. Com o arquivo criado, precisamos definir basicamente dois blocos, o primeiro é o de request (linhas 2 à 14):

O nosso bloco de REQUEST precisa conter o método HTTP da requisição, que para o gRPC é sempre POST. A url que é basicamente a junção de /nome_do_serviço/nome_do_método_rpc e o bodyPatterns que é onde estará as informações de payload da requisição. Sobre o bodyPatterns, dentro do bloco “equalToJson” temos as informações da request que seguem o o padrão nome_do_campo (que está no .proto) seguido de um dado qualquer. Fique atento ao que adiciona na request, pois caso o seu client (chamada do teste integrado) envie uma requisição com alguma informação divergente o grpc-wiremock não responderá conforme esperado.

Já o nosso bloco RESPONSE contém informações como status code da response e o body de retorno. Sobre o status, um problema que pode ocorrer é talvez adicionar um código que não existe conversão equivalente na API do gRPC, por exemplo código 201 created, nesses casos o grpc-wiremock não funcionará (já perdi algumas horas com um erro assim, fica a dica galera) na dúvida consulte esta tabela. Dentro do bloco jsonBody você deverá adicionar qual resposta você espera que aquela request devolva, no nosso caso o status é um campo da mensagem PaymentGrpcReply que possui um enum de valores possíveis, para atendê-lo basta adicionar a string do nome equivalente.

Passo 4: Executando o teste

Com tudo definido basta você executar o docker-compose criado anteriormente e esperar o serviço inicializar. Dentro do repositório deste artigo no meu GitHub adicionei códigos de testes para exemplificar o cenário e que você pode executar localmente para testar.

Execução dos testes de exemplo no repositório do artigo

Referências:

--

--

Tony Augusto

Desenvolvedor back-end Java e uma pessoa que acredita na propagação do conhecimento