DEV Community

Cover image for API Mocking with WireMock.Net
manoj
manoj

Posted on

API Mocking with WireMock.Net

In several situations where the software we developed interfaces some kind of REST based third party API that was not available during development. The interactions may be as simple as a service that more or less returns a simple document like a user list or as complicated as a workflow interaction, where the service results correlate somewhat with the call.

Probably the most obvious way to solve this is to provide some kind of mock that mimics the behavior of the actual service being called. These mocks often are some kind of dumping ground, because noone feels responsible for it (hey - it's actually what the third party does ;P). The code inside is mostly very simple, since it just implements a facade, which is just good enough, so that the system you are developing feels that everything needed is there.

Basic Concept

WireMock.Net allows to match requests to responsible responders by defining criteria for:

  • HTTP verb
  • URI
  • request headers
  • request body

A responder may either return a static or even dynamic result specifying:

  • status code
  • response headers
  • reponse body

Configuring

Configuration can happen via JSON files or a REST API, both of which are valuable options. The syntax used in both is identical, configuration via rest means uploading files with the same content as when using configuration files. There is just one thing to be careful about:

Make sure to use unique GUIDs, otherwise you will overwrite previous definitions.

Files

Files configuration is what I chose in my project at work. Here we want the mock to stick around for a long time and changes to the configuration are seldom and infrequent. We host WireMock inside IIS for the sake of convenience. A mappings json file defines matching rules for HTTP requests. This is very similar to what a route map looks like in ASP.NET MVC or express.js. Rules can apply to url, HTTP method, headers and body. For instance to map to a specific URL, an ExactMatcher can be used:

"Request": {
  "Path": {
    "Matchers": [
      {
        "Name": "ExactMatcher",
        "Pattern": "/V1/api/ShoppingCart"
      }
    ]
  },
}
Enter fullscreen mode Exit fullscreen mode

Exact matching won't be that useful for all rules, especially, if you peek into the request body. There are many more matchers, e.g. to evaluate XPath expressions, peek into JSON documents or evaluate C# expressions. The response for a matched request can either be defined inline or in a referenced file:

"Response": {
  "StatusCode": 200,
  "BodyAsFile": "shopping_cart.json",
  "UseTransformer": false,
  "Headers": {
    "Content-Type": "application/json; charset=utf-8",
    "api-supported-versions": "1.0"
  }
}
Enter fullscreen mode Exit fullscreen mode

Responses do not have to be static, you can use templating to project values from the request into the response or dynamically calculate the name of the file to return. Handlebars and Scriban are supported as engines.

"Response": {
    "Headers": { "Content-Type": "application/xml" },
    "BodyAsFile": "c:\\temp-wiremock\\__admin\\mappings\\_{{request.query.MyUniqueNumber}}_\\MyXmlResponse.xml",
  "UseTransformer": true
}
Enter fullscreen mode Exit fullscreen mode

To be able to template against a JSON request payload, there is even a helper function to use in templating to navigate JSON documents. All in all there is a lot you can do, but the learning curve is absolutely flat.

API

The API defines several endpoints to upload/download settings/files. All in all this is pretty self explanatory. I guess the main usecase for using the API is integrative unit testing, where you want to configure the mock with new routes, when a new test starts.

Hosting

There are multiple hosting options. You may host WireMock inside IIS, run it as a dotnet tool or self host it in your process.

IIS

I was unaware, how easy it would be to host this in IIS. I just had to include a web.config like this:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.webServer>
    <handlers>
      <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified"/>
    </handlers>
    <aspNetCore processPath="dotnet-wiremock.exe" arguments="--Port 80 --ReadStaticMappings true" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" forwardWindowsAuthToken="false"/>
  </system.webServer>
</configuration>
Enter fullscreen mode Exit fullscreen mode

To have access to the tools assemblies, I had to copy them to the directory of the web application:

  • dotnet-wiremock.exe went into the root folder
  • The .store folder and related subfolders went into the root follder
  • In addition I put the mappings.json file (and additional response files) into __admin\mapping.

Dotnet Tool

dotnet-wiremock.exe can just be run from the commandline and serves HTTP until being actively terminated. This is the easiest way to start off and configure or test matchers.

Self Hosted

WireMock can be spun up in a process by using it as a library. This is probably the smoothest integration for integrative unit tests.

Final Thoughts

With the experience I had so far with it, I would always try to stick to tools like this for your HTTP mocking needs if at all possible. Custom developed applications in my experience seem to be a dumping ground of bad code, which does not get any care or maintenance. Configuration based mocking with powerful tools like dynamic matchers allows to create configurable artifacts that can be checked in along with the regular code. Configuration is trivial if you have a solid knowledge of HTTP. When some reasonable rules have been created, even non-developers will be able to extend the configuration.

Cheers!!!

Top comments (1)

Collapse
 
stef profile image
Stef Heyenrath

Nice blog ;-)