How to Create a Standalone Wiremock Stub Server - Bug Reaper

                  Bug Reaper

Lean about Automation Testing,Selenium WebDriver,RestAssured,Appium,Jenkins,JAVA,API Automation,TestNG,Maven, Rest API, SOAP API,Linux,Maven,Security Testing,Interview Questions

Saturday, 7 March 2020

How to Create a Standalone Wiremock Stub Server

Why we need Mocking?

We are often in a need to create stubs or mocks when the API under test is not completely ready or we need to test the external systems without getting affected by any external environmental problems.

Requirements for our API service:

Our service has all the below specifications.

Endpoint URL (Base path and resource path)
Body
Query Parameters
Path Parameters
Headers

Our product type is courses and we can do below operations for shoppingcart service:

Create a shopping cart. (POST)
Get/Retrieve a shopping cart details. (GET)

Now let’s define the service requirements step by step.

Service URL
Base URL http://test.myshop.com
Base Path carts
Headers:

Content-Type application/json
Accept application/json
Version v1
Client Android
Authorization Bearer <token>


Create a Shopping Cart

Method: POST

Resource Path: No resource path required.

Example Request: POST /carts


Body:

Our shopping cart has customer and products attributes and they have their own attributes as shown below.

{

  "customer":{

    "id":"9879898787",

    "firstName":"Neeraj",

    "lastName":"Bakhtani",

    "email":"myemailId@gmail.com"

  },

  "products":[

    {

      "description":"Rest API mocking using WireMock",

      "type":"Course",

      "productAttributes":[

        {

          "courseLenght":"5 hours",
          "courseRating": "5 stars",

          "courseCreationDate":"2021-01-14",

          "courseLevel":"Advanced"

        }

      ],

      "price":{

        "amount": 100.0,

        "discount": 30.0,

        "paymetType":"VISA CREDIT CARD",

        "currency": "SGD"

      }

    }

  ]

}



Response:

{

  "customer":{

    "id":"9879898787",

    "firstName":"Neeraj",

    "lastName":"Bakhtani",

    "email":"myemailId@gmail.com"

  },

  "products":[

    {

      "description":"Rest API mocking using WireMock",

      "type":"Course",

      "productAttributes":[

        {

          "courseLenght":"5 hours",
          "courseRating": "5 stars",

          "courseCreationDate":"2021-01-14",

          "courseLevel":"Advanced"

        }

      ],

      "price":{

        "amount": 100.0,

        "discount": 30.0,

        "paymetType":"VISA CREDIT CARD",

        "currency": "SGD"
      }

    }

  ]

}


Get a Shopping Cart

Method: GET

Resource Path: {cartId}

Query Param: productCount (I added to distinguish 1 and 2 product mocking. Normally, we do not need this kind of QueryParams.)

Example Request: GET /carts/quil514c-9678-4a4b-b32d-550b7fc3cfb2?productCount=1

Response

{
  "id": "quil514c-9678-4a4b-b32d-550b7fc3cfb2",
  "customer": {
    "id": "9879898787",
    "firstName": "Neeraj",
    "lastName": "Bakhtani",
    "email": "myemailId@gmail.com"
  },
  "products": [
    {
      "id": "93b55282-334c-48b0-a8f7-a9d5eef9c4b9",
      "description": "Rest API mocking using WireMock",
      "type": "Course",
      "productAttributes": [
        {
          "courseLenght": "5 hours",
          "courseRating": "5 stars",
          "courseCreationDate": "2021-01-14",
          "courseLevel": "Advanced"
        }
      ],
      "price": {
        "amount": 100.0,
        "discount": 30.0,
        "paymetType": "VISA CREDIT CARD",
        "currency": "SGD"
      }
    }
  ]
}

Standalone WireMock Stub Server Creation

Now, we can create a stub server based on our requirements.

Step-1: Add Required Dependencies to pom.xml

Example

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>WireMockTesting</artifactId>
    <version>1.0-SNAPSHOT</version>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>8</source>
                    <target>8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <dependencies>
        <dependency>
            <groupId>com.github.tomakehurst</groupId>
            <artifactId>wiremock</artifactId>
            <version>2.25.1</version>
        </dependency>

        <dependency>
            <groupId>org.json</groupId>
            <artifactId>json</artifactId>
            <version>20190722</version>
        </dependency>

        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.8.6</version>
        </dependency>

        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>5.5.2</version>
        </dependency>
    </dependencies>

</project>


Step-2: Create Mock JSON Files

test -> resources -> __files package. I also added extra one more package as json but it is not necessary because we are creating a stub server for REST API with JSON.

Step-3: Coding the Stub Server

JsonUtil.java

This class does a very basic JSON read operation. We will use setJSON and getJSON methods in our stub creation methods.

package utils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import org.json.JSONObject;
import org.json.JSONTokener;

public class JsonUtil{
    public JSONObject jsonObject;
    private File jsonFile;

    public JSONObject getJSON() {
        return jsonObject;
    }

    public JsonUtil setJSON(String path) {
        jsonFile = new File(System.getProperty("user.dir") + "/src/test/resources/" + path);
        jsonObject = readJSONAsJSONObject();
        return this;
    }

    public JSONObject readJSONAsJSONObject() {
        InputStream is = null;
        try {
            is = new FileInputStream(jsonFile);
        }
        catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        JSONTokener jsonTokener = new JSONTokener(is);
        jsonObject = new JSONObject(jsonTokener);
        return jsonObject;
    }
}


Stubs.java
In this class, we will create our mocks. Based on Wiremock functionalities, we will use different approaches to create these mocks.

import com.github.tomakehurst.wiremock.WireMockServer;
import utils.JsonUtil;

import static com.github.tomakehurst.wiremock.client.WireMock.*;

public class Stubs {
    private JsonUtil jsonUtil;
    public WireMockServer wireMockServer;

    public Stubs setUp() {
        wireMockServer = new WireMockServer(3467);
        wireMockServer.start();
        jsonUtil = new JsonUtil();
        return this;
    }

    public Stubs resetServer() {
        wireMockServer.resetAll();
        return this;
    }

    public Stubs stubForCreateCart(String responseFileName) {
        wireMockServer.stubFor(post("/carts")
                .withHeader("Content-Type", equalToIgnoreCase("application/json"))
                .withHeader("Accept", equalToIgnoreCase("application/json"))
                .withHeader("Version", equalToIgnoreCase("v1"))
                .withHeader("Client", equalToIgnoreCase("Android"))
                .withHeader("Authorization", equalToIgnoreCase("Bearer MySecretToken"))
                .withRequestBody(matchingJsonPath("$.customer.firstName", equalTo("Neeraj")))
                .withRequestBody(matchingJsonPath("$.customer.lastName", equalTo("Bakhtani")))
                .willReturn(aResponse()
                        .withStatus(201)
                        .withHeader("Content-Type", "application/json")
                        .withBodyFile("json/" + responseFileName)));
        return this;
    }


    public Stubs stubForGetCartSingle(String responseFileName) {
        wireMockServer.stubFor(get("/carts/quil514c-9678-4a4b-b32d-550b7fc3cfb2?productCount=1")
                .willReturn(aResponse()
                        .withStatus(200)
                        .withHeader("Content-Type", "application/json")
                        .withBodyFile("json/" + responseFileName)));
        return this;
    }


    public Stubs status() {
        System.out.println("Stubs Started!");
        return this;
    }
}


StubServerMain.java
We will chain our stub creation methods in the main class.

public class StubServerMain {

    public static Stubs stubs = new Stubs();

    public static void main(String[] args) {
        stubs.setUp()
                .stubForCreateCart("CreateCartSuccessResponse.json")
                .stubForGetCartSingle("CreateCartSuccessResponse.json")
                .status();
    }
}

Find sample code in Git

https://github.com/neeraj19a/MockingAPIUsingWireMock

Use Potman Collection file: Sample API for Test.postman_collection.json (in above Git Link only)

To run this As Application


click Run--> Edit Configuration
click +



No comments:

Post a Comment