API mocking in C# with WireMock.Net
This post was published on February 24, 2022Those of you who have been reading my blog posts for a while probably know I am a big fan of WireMock, the open source API mocking / service virtualization tool written in Java. I’ve even created and published a free and open source workshop around the tool.
I only much more recently found out, while preparing an API testing course in C# for a client, that WireMock has been ported to C# as well. In this blog post, I’d like to take a closer look at WireMock.Net, as the library is (rather predictably) called. Before we do that, all credits for writing and maintaining the library go to Stef Heyenrath.
I’m not going to dive too deeply into the use cases for WireMock.Net, as it has the exact same purpose as the ‘original’ WireMock: allowing you to mock internal or external APIs in order to write more efficient tests and test earlier, more and more often. This is also not an exhaustive overview of all WireMock.Net features, but rather a collection of examples of what I think are its most important or powerful capabilities.
Defining and testing a first mock API response
After adding WireMock.Net to your project using the NuGet package, using WireMock.Net to mock an API call in a test can be done as follows:
We could then write a test for this mock API using RestSharp, for example:
This test will pass, telling us that our mock API works as expected.
Now that we’ve established how WireMock.Net works, let’s have a look at some key features I look for in all API mocking tools and libraries, and see how WireMock.Net implements those.
Request matching strategies
The first thing I usually explore in API mocking tools is their capabilities regarding request matching, or the identification of specific characteristics of a request in order to determine the appropriate response.
As mentioned in the documentation on request matching, WireMock.Net can match requests based on path or URL, HTTP method, query parameters, headers, cookies and request bodies.
The example above introduced two of these request matching strategies already, being the URL and the HTTP method. The mock defined there only responds to HTTP GET calls to the /hello-world
endpoint.
Let’s look at a couple of other examples, starting with matching requests that do (or do not) contain a specific header with a specific value. This is very useful, for example, when dealing with API authentication mechanisms.
Other than the ExactMatcher
, which checks for an exact value match, there are a number of other useful matchers available, including various JSON matchers and a regex matcher.
We can also match on JSON request body elements, like in this example:
This will return a match for this request body, for example:
{ "cars": [ { "make": "Alfa Romeo" }, { "make": "Lancia" } ] }
Simulating faults and delays
One thing where using mocks shines over having to deal with real dependencies is testing the resilience of your system against faulty or unexpected behaviour of such a dependency. Where delays and errors are often really hard, if not impossible to trigger in a real dependency, it is just another bit of behaviour to model in a mock.
Next to returning HTTP 4xx or 5xx response status codes, which is a matter of passing the right value to the WithStatusCode()
method when building your response, WireMock.Net also supports other types of unexpected behaviour. Here’s an example that returns a valid response, but with a predefined delay:
Using WithDelay()
allows you to model performance behaviour and check that dependency timeouts and delayed responses are handled correctly in your application under test.
WireMock.Net also provides some capabilities for returning malformed responses:
Creating stateful stubs
Another useful mocking feature is the ability to simulate statefulness (‘memory’). Sometimes, you want to model stateful behaviour, i.e., behaviour where the order in which incoming requests arrive is significant.
WireMock.Net supports this through building finite state machines (FSMs), i.e., collections of states and state transitions:
An HTTP GET request to /todo/items
arriving before a POST to the same endpoint will return a to-do list with a single item ‘Buy milk’ on it, whereas that same GET call, when received after a POST, will return a to-do list containing both ‘Buy milk’ and ‘Cancel newspaper subscription’.
Response templating
The final feature I typically investigate when looking at an API mocking tool is its ability to reuse values from an incoming request in the corresponding response.
This is useful when dealing with values that are necessary for successful processing of a response on the consumer side, but that are impossible to predict beforehand. Think transaction or session IDs, cookies, and other such values.
Like its Java counterpart, WireMock.Net supports reusing request values through response templating. Here’s an example that inspects the request, extracts the HTTP method used and echoes that in the response body:
The WithTransformer()
method has to be added to the response definition, otherwise the response body will include the literal value `` as no response templating will be applied.
Unfortunately, there does not seem to be a way to apply this on a global level (as can be done in the WireMock in Java, so you will need to add this to each mock response definition.
Here’s another example that uses response templating, this time to extract a value from the request JSON body to reuse it in the plain text response body:
As you can see, WireMock.Net allows you to extract element values from a (JSON) request body using JsonPath expressions and reuse them, for example to repeat them in response bodies.
That wraps up this first look at WireMock.Net. Again, it is by no means meant to be a complete overview of everything that WireMock.Net can do for you, but rather a look at some features I find particularly interesting and valuable.
I’ve been pleasantly surprised by its ease of use, although I must admit I probably had an unfair advantage having a couple of years of experience with WireMock in Java under my belt. I’m looking forward to further explore WireMock.Net in the future.
If you’d like to know more about WireMock.Net, I recommend you have a look at the docs. I’ve put all the examples I used in this blog post on GitHub, together with NUnit + RestSharp tests to demonstrate that the mock API responses work as expected.
"