Ohhh aleluia… saiu um post! rsrs… Demorei, mas agora vou ter tempo para escrever dois posts sobre o que é o Mock Server, para que ele serve e como podemos utilizá-lo em cenários de testes ou para agilizar o desenvolvimento. Nesse primeiro post, vou focar no objetivo e conceitos. No próximo será uma implementação demonstrando um cenário mais próximo da realidade, usando Mock Server. 🙂
Iniciando, posso te dizer que ele é muito útil e tenho utilizado dentro da empresa que trabalho atualmente em vários projetos. Espero que você goste do conteúdo!
O que é Mock Server?
Mock Server pode ser uma ferramenta (Postman, Fiddler, etc) configurada no servidor (cloud ou On-premise), ou container Docker, ou ainda ser um serviço. O objetivo dele é simular todas as requests (solicitações) via HTTP ou HTTPS que são feitas para endpoints de outros serviços. Em outras palavras, o Mock Server retornará o resultado esperado pelo serviço solicitante e não aciona o endpoint externo original. Este isolamento é realizado dentro do serviço solicitante, configurando o Mock Server, e assim evita dependências externas. Basicamente, utilizando ele, você vai conseguir retirar o acoplamento de serviços externos nos testes de Integração, Performance e de Comportamento.
Normalmente, quando você depende de um serviço externo, você tem esse cenário abaixo no momento da realização de testes:
Neste diagrama, há uma Aplicação que possui quatro dependências de endpoints de serviços externos W, X, Y e Z.
Neste caso, ao executar os testes da Aplicação, o contexto vai se “estender” aos serviços externos, porque a aplicação depende diretamente destes serviços. Isso é um cenário comum, mas com efeitos ruins, por exemplo: se o Endpoint do Serviço Z estiver fora, os testes na Aplicação principal não vão executar ou vão gerar erros, contudo o problema está em uma dependência externa. Uma situação similar iria ocorrer se o Serviço Z estiver instável. Então, nesse caso, vai gerar um trabalho de análise ou avaliação do erro desnecessariamente. Além de inviabilizar a execução dos testes neste caso.
Contudo, ao utilizar o Mock Server o contexto da Aplicação fica desta maneira:
Assim, o cenário fica diferente e não há dependências diretamente para serviços externos, neste caso para os quatro serviços W, X, Y e Z. Com a entrada do Mock Server, o contexto da Aplicação fica isolado e os resultados enviados pelos endpoints são simulados. Evitando erros e falhas nos testes devido o acoplamento com serviços externos.
Ao executar os testes, a aplicação terá as suas dependências apontadas para o Mock Server, assim quando forem realizadas requests para os endpoints dos serviços externos o Mock Server vai identificar e retornar o valor esperado para cada endpoint, configurado anteriormente. Nós informamos ao Mock Server sobre os valores esperados através da Expectation.
O que é Expectation?
Uma expectation define a ação que será executada pelo Mock Server para simular o comportamento que os testes estavam esperando do serviço externo. Indo para uma visão mais técnica, as expectations são JSONs que contêm as informações das requests que serão enviadas ao Mock Server e suas respectivas respostas esperadas no cenário do teste.
Por meio da expectation, é possível criar objetos que possuem dados ou comportamentos esperados do serviço externo. Isso é similar com a abordagem de criar objeto mock em um teste de unidade, mas neste caso a expectation simula o retorno de um endpoint de qualquer serviço externo.
Como havia falado acima, em cada expectation existem configurações para a Request, para a Response (headers e body da response) e pode ter um tempo de expiração, por exemplo:
{
"httpRequest": {
"method": "GET",
"path": "/v1/cep/05797000",
"headers": []
},
"httpResponse": {
"statusCode": 200,
"headers": [
{
"name": "Content-Type",
"values": [
"application/json"
]
}
],
"body": "{'bairro': 'Jardim Ip\u00ea', 'cidade': 'S\u00e3o Paulo', 'logradouro': 'Rua Gast\u00e3o Raul de Forton Bousquet', 'estado_info': {'area_km2': '248.221,996', 'codigo_ibge': '35', 'nome': 'S\u00e3o Paulo'}, 'cep': '05797000', 'cidade_info': {'area_km2': '1521,11', 'codigo_ibge': '3550308'}, 'estado': 'SP'}"
}
}
Essa expectativa acima é do endpoint /v1/cep/ do serviço http://api.postmon.com.br/ com o parâmetro 05797000. Basicamente, esse endpoint vai buscar o nome do bairro, cidade, logradouro, cidade, estado e informações da área do CEP informado. Nesse caso, o CEP foi o 05797000.
Como você pode verificar, dentro do httpRequest têm as propriedades relacionadas ao matcher de request. Elas são usadas para verificar se a request tem a expectativa esperada para ser aplicada à ação. Essas propriedades são:
- method: o tipo do verso HTTP do endpoint (neste caso “GET”);
- path: o caminho do endpoint com o parâmetro (neste caso o caminho “/v1/cep/” e o parâmetro “05797000”);
- headers: o cabeçalho da request, se existir.
Dentro do httpResponse têm as propriedades relacioandas às ações que vão ser realizadas, no caso de uma request que deu match com as configurações informada na propriedade httpRequest. Essa ação pode ser response, forward, callback e erro. Neste caso, estamos usando como response, então essas propriedades são:
- statusCode: o status HTTP esperado no returno (neste caso o status 200);
- headers: o cabeçalho esperado no returno (neste caso um retorno padrão com JSON);
- body: o resultado da request (neste caso, o resultado foi igual ao verdadeiro).
Através destas configurações acima, estou simulando o comportamento de uma request para:
http://api.postmon.com.br/v1/cep/05797000; assim, desacoplando essa dependência do meu serviço.
Conclusão
Como visto nas seções acima, ao usarmos a abordagem com Mock Server a aplicação fica completamente isolada. Isso é fundamentalmente excelente no contexto de testes, como o Teste de Integração, de Performance ou de Comportamento, fazendo com que requests para um endpoint externo seja controlado, retornando assim resultados esperados nos testes. Outro ponto importante destacar é que em testes de Performance a aplicação não terá interferência de latência em cenários que as requests são feitas para as endpoints externas.
Conseguimos fazer isso através da configuração de Expectation, resumidamente, um arquivo JSON com propriedades para informarmos a request matcher (o endpoint junto com o parâmetro de entrada que vamos enviar nos testes) e a ação com o retorno esperado.
Os principais benefícios ao usar Mock Server no contexto dos testes, são:
- Diminua o acoplamento nos testes que dependem de APIs externos;
- Isola completamente os comportamentos esperados das APIs externas;
- Melhorar o tempo de resposta do teste, pois não terá latência;
- Evita a interferência de problemas nos testes.
É isso aí! Em breve vou postar o próximo post, demonstrando uma implementação do Mock Server dentro de uma aplicação.
Referências
- Mock Server: https://www.mock-server.com/
- MockServer Wikipedia: https://en.wikipedia.org/wiki/MockServer
- Mock Server — save time and money during development and testing: https://medium.com/billie-finanzratgeber/mock-server-save-time-and-money-during-development-and-testing-bf1d74364d84