Como solucionar problemas do WireMock.Net + quatro problemas comuns
Introdução
WireMock.Net é uma ótima ferramenta para remover dependências externas ao escrever testes de integração, mas como é altamente configurável, pode ser difícil descobrir por que seus mocks não estão funcionando.
Neste post, explicarei como solucionar problemas em sua configuração e mostrarei alguns problemas comuns que acontecem no meu trabalho diário.
O que é WireMock.Net?
WireMock.Net é uma biblioteca para stubbing e mocking APIs HTTP. Escrevi sobre como e por que usá-lo anteriormente e usarei os exemplos do post anterior neste.
API de administração do WireMock.Net
WireMock.Net tem uma API de administração que é essencial para depurar problemas em nossos mocks.
A API oferece muitos endpoints, mas mostrarei os dois que serão usados para encontrar problemas nos mocks.
O endpoint /__admin/mappings retorna os mappings configurados para os mocks, incluindo todos os matchers que precisam ser cumpridos para que o mock responda e a resposta que será retornada.
O endpoint /__admin/requests retorna o histórico de solicitações feitas ao WireMock. Ele inclui informações sobre a solicitação feita e a resposta recebida pelo solicitante.
Ele também inclui a propriedade PartialRequestMatchResult, que mostra qual matcher foi bem-sucedido e qual não foi.
Aqui está um exemplo de uma solicitação que atingiu o mock:
O RequestMatchResult mostra que o mock tem 2 matchers configurados (TotalNumber) e a pontuação total foi 2 (TotalScore). O MatchDetails também mostra uma pontuação de 1.0 (100%) para todos os matchers.
Aqui está um exemplo de uma solicitação que não cumpriu todos os matchers:
O PartialRequestMatchResult mostra que o mock tem 2 matchers configurados (TotalNumber) e a pontuação total foi 1 (TotalScore). No MatchDetails podemos ver que o problema estava no PathMatcher.
Olhando no endpoint de mappings, vemos que o caminho foi configurado para /pokemon/charmander, em vez de /pokemon/squirtle que estava na solicitação.
Configurando a Interface de Administração
Para usar a interface de administração, precisamos apenas iniciar o servidor do WireMock com o método StartWithAdminInterface em vez do método Start:
[Fact]publicasyncTaskGet_Existing_Pokemon_Returns_200(){//ArrangevarwireMockSvr=WireMockServer.StartWithAdminInterface();//Inicia o WireMock com a Interface de AdministraçãovarFactory=_factory.WithWebHostBuilder(builder=>{builder.UseSetting("PokeApiBaseUrl",wireMockSvr.Url);});varHttpClient=Factory.CreateClient();Fixturefixture=newFixture();varResponseObj=fixture.Create<PokemonInfo>();varResponseObjJson=JsonSerializer.Serialize(ResponseObj);wireMockSvr.Given(Request.Create().WithPath("/pokemon/charmander").UsingGet()).RespondWith(Response.Create().WithBody(ResponseObjJson).WithHeader("Content-Type","application/json").WithStatusCode(HttpStatusCode.OK));//ActvarHttpResponse=awaitHttpClient.GetAsync("/pokemoninfo/charmander");awaitTask.Delay(TimeSpan.FromMinutes(30));//Atraso para poder examinar a interface de administração//AssertHttpResponse.StatusCode.Should().Be(HttpStatusCode.OK);varResponseJson=awaitHttpResponse.Content.ReadAsStringAsync();varPokemonInfo=JsonSerializer.Deserialize<PokemonInfo>(ResponseJson);PokemonInfo.Should().BeEquivalentTo(ResponseObj);wireMockSvr.Stop();}
Problemas comuns
Parâmetros de string de consulta
Vamos pegar o endpoint /pokemon?type={typeName} como um exemplo.
Ao contrário dos parâmetros na string de consulta, os parâmetros no caminho não funcionarão quando configurados com WithParam. Por exemplo, o endpoint /pokemon/{pokemonName} não será alcançado com:
Ao executar atrás de um proxy de rede, o WireMock pode estar inacessível, causando um tempo limite no aplicativo.
Para ignorar o proxy para localhost, precisamos configurar a variável de ambiente no_proxy, adicionando localhost ao seu valor (mais valores podem ser incluídos, separados por vírgula):
Configuração da variável de ambiente no_proxy
Servidor WireMock compartilhado para todos os testes
Compartilhar a instância do servidor do WireMock entre os testes pode causar problemas aleatórios porque as definições de mock são substituídas quando configuradas pela segunda vez. Por exemplo, pegue dois testes em execução em paralelo:
O Teste 1 configura /pokemon/charmander para retornar o status 200;
O Teste 2 configura /pokemon/charmander para retornar o status 404.
O primeiro teste a configurar o mock será interrompido porque seu mock será substituído e o resultado não será o esperado.
Para evitar esses problemas aleatórios, precisamos usar uma instância WireMock para cada teste: