How to troubleshoot WireMock.Net problems + four common problems
Introduction
WireMock.Net is a great tool to remove external dependencies when writing integration tests, but because it is highly configurable, it can be hard to find why its mocks aren’t working.
In this post, I’ll explain how to troubleshoot problems in its configuration and show some common problems that happen in my day-to-day work.
What is WireMock.Net?
WireMock.Net is a library for stubbing and mocking HTTP APIs. I wrote about how and why to use it previously, and will use the previous post examples in this one.
WireMock.Net’s Admin API
WireMock.Net has an Admin API that is essential for debugging problems in our mocks.
The API offers many endpoints, but I’ll show the two that will be used to find problems in the mocks.
The endpoint /__admin/mappings returns the mappings configured for the mocks, including all the matchers that need to be fulfilled for the mock to respond, and the response that will be returned.
The endpoint /__admin/requests returns the history of requests made to WireMock. It includes information about the request made and the response received by the requester.
It also includes the PartialRequestMatchResult property, that shows which matcher was successful and which was not.
Here is an example of a request that reached the mock:
The RequestMatchResult shows that the mock has 2 matchers configured (TotalNumber) and the total score was 2 (TotalScore). The MatchDetails also shows a score of 1.0 (100%) for all the matchers.
Here is an example of a request that didn’t fulfill all of the matchers:
The PartialRequestMatchResult shows that the mock has 2 matchers configured (TotalNumber) and the total score was 1 (TotalScore). In the MatchDetails we can see that the problem was on the PathMatcher.
Looking in the mappings endpoint, we see that the path was configured to /pokemon/charmander, instead of the /pokemon/squirtle that was in the request.
Configuring the Admin Interface
To use the admin interface, we just need to start WireMock’s server with the StartWithAdminInterface method instead of the Start method:
[Fact]publicasyncTaskGet_Existing_Pokemon_Returns_200(){//ArrangevarwireMockSvr=WireMockServer.StartWithAdminInterface();//Start WireMock with Admin InterfacevarFactory=_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));//Delay to be able to examine the admin interface//AssertHttpResponse.StatusCode.Should().Be(HttpStatusCode.OK);varResponseJson=awaitHttpResponse.Content.ReadAsStringAsync();varPokemonInfo=JsonSerializer.Deserialize<PokemonInfo>(ResponseJson);PokemonInfo.Should().BeEquivalentTo(ResponseObj);wireMockSvr.Stop();}
Common problems
Query string params
Let’s take the endpoint /pokemon?type={typeName} as an example.
Contrary to params in the query string, params in the path won’t work when configured with WithParam. For example, the endpoint /pokemon/{pokemonName} won’t be reached with:
When running behind a network proxy, WireMock may be unreachable, causing a timeout in the application.
To ignore the proxy for localhost, we need to configure the no_proxy environment variable, adding localhost to its value (more values can be included, separated by comma):
no_proxy environment variable configuration
Shared WireMock server for all tests
Sharing WireMock’s server instance between tests can cause random problems because mock definitions are overridden when configured for the second time. For example, take two tests running in parallel:
Test 1 configures /pokemon/charmander to return status 200;
Test 2 configures /pokemon/charmander to return status 404.
The first test to configure the mock will break because its mock will be overridden and the result won’t be as expected.
To avoid this random problems, we need to use one WireMock instance for each test: