Wednesday, August 16, 2017

Using Wiremock for quick and easy http mocks of your API

I published this article at the turn of the year in my company's internal blog. I am republishing it here thinking it might be useful to outside world who are looking at a concise guide.

WireMock is an HTTP mock server. At its core it is web server that can be primed to
  1. serve canned responses to particular requests (stubbing) and 
  2. that captures incoming requests so that they can be checked later (verification).
Imagine your application component is dependent on some other component for development or testing, here WireMock can come in and remove your dependency headaches.
You can agree the contract, design the stub and use it for your own component without tight integration with other component. This makes the development and testing much
easier and faster.
WireMock also helps in situations when you want to test against a variety of parameters but you have programming limitations or other complexity/error factors. You can read more
in the official website. 
WireMock comes as a jar file that you can either
  • use as a library in your Java code (or any JVM application), or
  • run as a standalone process in your localhost or remote.
All of WireMock’s features are accessible via its REST (JSON) interface and its Java API. Additionally, stubs can be configured via JSON files.
Here we are talking about basic info on running it as a standalone process.

Running the server with stub

Step 1: Download the latest jar from http://wiremock.org/.
Step 2: Run the jar.
$ java -jar wiremock-standalone-2.4.1.jar
By default this will start the mock server on http port 8080, which is available at:
http://<host>:8080
When the WireMock server starts it creates two directories under the current one: mappings and __files in the same directory as of the jar by default.
some_folder
        |---- __files
        |---- mappings
        |---- wiremock-standalone-2.4.1.jar
Step 3: Put the mapping and/or any stub response in a .json file inside mappings. 
If you want to manage the stub in multiple files, drop it under __files, and map it against particular request in the .json file inside mappings.
Step 4: For contents to be reflected, restart server. 
Step 5: Use browser, or any client like Postman to test it. You can also integrate the end point in your application code like any normal URL.

Note: There are different flags like --port--https-port etc to start the application with that you can get from official website so as to match your requirements.

Example:
For the following outcome:

localhost snapshot
We did the following:
  1. Created a mapping.json file inside mappings folder with following content.
    {
        "request": {
            "method": "GET",
            "url": "/api/mytest"
        },
        "response": {
            "status": 200,
            "body": "More content\n"
        }}

    We have stubbed the response with "More Content" text here directly so we did not use __files folder. 
    If any of the request method or URL does not matches, server will return 404.

  2. Started the server:
    $ java -jar wiremock-standalone-2.4.1.jar

Here's the folder structure:
my_folder
        |---- __files

        |---- mappings
                |---- mapping.json

        |---- wiremock-standalone-2.4.1.jar

We can do request matching based on request body or other request parameters also like URL, headers, method etc, and put in multiple mapping .json files inside mappings.
When the stub is not simple and we want to keep them arranged in our server, we can put them in files inside __files, and provide their names inside the corresponding mapping files.
Following mapping gives an example of request body matching and maps it to a particular stub file.
{
    "request": {
        "method": "POST",
        "bodyPatterns": [
            {
                "contains":"type: CREDIT"
            }
        ]
    },
    "response": {
        "status": 200,
        "bodyFileName":"Credit_Response.json"
    }
}
The folder structure for above is:
my_folder
        |---- __files
                |---- 
Credit_Response.json
        |---- mappings
                |---- mapping.json

        |---- wiremock-standalone-2.4.1.jar

Verification

WireMock maintains the log of all requests in-memory since most recent server startup. This is in JSON format. This is a critical resource for auditing for success/failure cases.
  1. Hitting a GET request to /__admin/requests will return all requests. For example: http://localhost:8080/__admin/requests.
  2. Hitting a GET request to /__admin/requests/unmatched will return all unmatched requests.
Similarly, there are other locations too. Refer official doc.

Reference: http://wiremock.org/


Q. Doesn't seem to work for protobuff requests. What is the way around?

Info. Protobuff is a message transfer format like json or XML, from Google.

A. For textual formats like txt or json, JSONPath can be used to identify some keywords in the request body. But this won't work for protobuf or other formats where JSONPath can't traverse itself. So following is the way in my idea:
  1. Generate stubs at own end aforehand, serialize them and place in _files directory.
  2. For request matching, do either of the following:
    2.1. Include request header with key-value pairs that you'd like to identify, and look for them in your mapping file. I'd recommend for ease of use.
    2.2 For request body searching, you need to write custom matcher class that can deserialize, read through the request body and returns whether the identification was found or not, then based upon mapping, return the already placed stub.
  3. While returning response, return the mapped serialized file with appropriate headers such as Content-Type
For complete control, like dynamic response generation etc, you need to write and place the whole implementation in wiremock and use (jar in java). This is an overkill for simple mocking purpose.

No comments:

Post a Comment

Liked or hated the post? Leave your words of wisdom! Thank you :)