Repository: authorjapps/zerocode
Pull request #48 (2018-03-11 13:10:18)

ISSUE-47 # WireMock - Optional dynamic mock.api.port for downstream s…
…ervices


Patch:
diff --git a/src/main/java/org/jsmart/zerocode/core/domain/MockStep.java b/src/main/java/org/jsmart/zerocode/core/domain/MockStep.java
index 37382f45..988637ea 100644
--- a/src/main/java/org/jsmart/zerocode/core/domain/MockStep.java
+++ b/src/main/java/org/jsmart/zerocode/core/domain/MockStep.java
@@ -3,7 +3,13 @@ package org.jsmart.zerocode.core.domain;
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
 import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import org.jsmart.zerocode.core.di.ObjectMapperProvider;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
 
 @JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
 /**
@@ -19,7 +25,14 @@ public class MockStep {
     private final JsonNode response;
     private final JsonNode assertions; //<-- In case the wiremock or simulator mock throws a status code etc
 
+    // derived value i.e. body as JSON string
+    private String body;
+
+    // derived value i.e. headers as JSON string
+    private String headers;
 
+    // derived value ie headers as Map
+    private Map<String, Object> headersMap;
 
     public String getName() {
         return name;
@@ -45,6 +58,31 @@ public class MockStep {
         return assertions;
     }
 
+    public String getBody() {
+        final JsonNode bodyNode = request.get("body");
+        return bodyNode != null ? request.get("body").toString() : null;
+    }
+
+    public String getHeaders() {
+        return request.get("headers").toString();
+    }
+
+    public Map<String, Object> getHeadersMap() {
+        ObjectMapper objectMapper = new ObjectMapperProvider().get();
+        HashMap<String, Object> headersMap = new HashMap<>();
+        try {
+            final JsonNode headersNode = request.get("headers");
+            if (null != headersNode) {
+                headersMap = (HashMap<String, Object>) objectMapper.readValue(headersNode.toString(), HashMap.class);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new RuntimeException(e);
+        }
+
+        return headersMap;
+    }
+
     @JsonCreator
     public MockStep(
             @JsonProperty("name") String name,
diff --git a/src/main/java/org/jsmart/zerocode/core/engine/executor/JsonServiceExecutorImpl.java b/src/main/java/org/jsmart/zerocode/core/engine/executor/JsonServiceExecutorImpl.java
index 6ead1e9f..2b168d98 100644
--- a/src/main/java/org/jsmart/zerocode/core/engine/executor/JsonServiceExecutorImpl.java
+++ b/src/main/java/org/jsmart/zerocode/core/engine/executor/JsonServiceExecutorImpl.java
@@ -4,6 +4,7 @@ import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.google.inject.Inject;
+import com.google.inject.name.Named;
 import com.jayway.jsonpath.JsonPath;
 import com.jayway.jsonpath.PathNotFoundException;
 
@@ -32,12 +33,20 @@ public class JsonServiceExecutorImpl implements JsonServiceExecutor {
     //guice
     @Inject
     private JavaExecutor javaExecutor;
+
     @Inject
     private ObjectMapper objectMapper;
+
     @Inject
     SmartUtils smartUtils;
+
     @Inject
     BasicHttpClient httpClient;
+
+    @Inject(optional = true)
+    @Named("mock.api.port")
+    private int mockPort;
+
     //guice
 
     public JsonServiceExecutorImpl() {
@@ -90,8 +99,6 @@ public class JsonServiceExecutorImpl implements JsonServiceExecutor {
         HashMap headers = (HashMap) readJsonPathOrElseNull(requestJson, "$.headers");
         Object bodyContent = readJsonPathOrElseNull(requestJson, "$.body");
 
-        final javax.ws.rs.core.Response serverResponse = httpClient.execute(httpUrl, methodName, headers, queryParams, bodyContent);
-
         /*
          * $MOCK: Create mock endpoints supplied for this scenario
          */
@@ -102,6 +109,8 @@ public class JsonServiceExecutorImpl implements JsonServiceExecutor {
             return "{\"status\": 200}";
         }
 
+        final javax.ws.rs.core.Response serverResponse = httpClient.execute(httpUrl, methodName, headers, queryParams, bodyContent);
+
         /*
          * now read the response for :
          * - headers
@@ -151,11 +160,18 @@ public class JsonServiceExecutorImpl implements JsonServiceExecutor {
 
             MockSteps mockSteps = smartUtils.getMapper().readValue(requestJson, MockSteps.class);
 
-            createWithWireMock(mockSteps);
+            if(mockPort > 0){
+                createWithWireMock(mockSteps, mockPort);
 
-            LOGGER.info("#SUCCESS: End points simulated via wiremock.");
+                LOGGER.info("#SUCCESS: End points simulated via wiremock.");
 
-            return true;
+                return true;
+            }
+
+            LOGGER.error("\n\n#DISABLED: Mocking was not activated as there was no port configured in the properties file. \n\n " +
+                    "Usage: e.g. in your <env host config .properties> file provide- \n " +
+                    "mock.api.port=8888\n\n");
+            return false;
         }
 
         else if(httpUrl.contains("/$MOCK") && methodName.equals("$USE.VIRTUOSO")){
diff --git a/src/main/java/org/jsmart/zerocode/core/engine/mocker/RestEndPointMocker.java b/src/main/java/org/jsmart/zerocode/core/engine/mocker/RestEndPointMocker.java
index fa7db919..3d094210 100644
--- a/src/main/java/org/jsmart/zerocode/core/engine/mocker/RestEndPointMocker.java
+++ b/src/main/java/org/jsmart/zerocode/core/engine/mocker/RestEndPointMocker.java
@@ -1,51 +1,119 @@
 package org.jsmart.zerocode.core.engine.mocker;
 
 import com.github.tomakehurst.wiremock.WireMockServer;
+import com.github.tomakehurst.wiremock.client.MappingBuilder;
+import com.github.tomakehurst.wiremock.client.ResponseDefinitionBuilder;
 import com.github.tomakehurst.wiremock.client.WireMock;
 import org.apache.commons.lang.StringUtils;
+import org.jsmart.zerocode.core.domain.MockStep;
 import org.jsmart.zerocode.core.domain.MockSteps;
+import org.jsmart.zerocode.core.engine.executor.JsonServiceExecutorImpl;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Map;
 
 import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
+import static com.github.tomakehurst.wiremock.client.WireMock.equalTo;
+import static com.github.tomakehurst.wiremock.client.WireMock.equalToJson;
+import static com.github.tomakehurst.wiremock.client.WireMock.get;
 import static com.github.tomakehurst.wiremock.client.WireMock.givenThat;
+import static com.github.tomakehurst.wiremock.client.WireMock.post;
+import static com.github.tomakehurst.wiremock.client.WireMock.put;
 import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
 import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
-import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
 
 public class RestEndPointMocker {
+    private static final Logger LOGGER = LoggerFactory.getLogger(JsonServiceExecutorImpl.class);
 
-    public static void createWithWireMock(MockSteps mockSteps) {
-        WireMockServer wireMockServer = new WireMockServer(wireMockConfig().port(8888)); //<-- Strange
-        wireMockServer.start();
-        WireMock.configureFor("localhost", 8888); //<-- Repetition of PORT
+    public static WireMockServer wireMockServer;
+
+    public static void createWithWireMock(MockSteps mockSteps, int mockPort) {
+
+        restartWireMock(mockPort);
 
-        // TODO - Check wiremock APIs to whether it supports method as a paramater or direct JSON
         mockSteps.getMocks().forEach(mockStep -> {
             String jsonBodyRequest = mockStep.getResponse().get("body").toString();
 
             if("GET".equals(mockStep.getOperation())){
-                givenThat(WireMock.get(urlEqualTo(mockStep.getUrl()))
-                        .willReturn(aResponse()
-                                .withStatus(mockStep.getResponse().get("status").asInt())
-                                .withHeader("Content-Type", APPLICATION_JSON)
-                                .withBody(jsonBodyRequest)));
+                LOGGER.info("*****WireMock- Mocking the GET endpoint");
+                givenThat(createGetRequestBuilder(mockStep)
+                        .willReturn(responseBuilder(mockStep, jsonBodyRequest)));
+                LOGGER.info("WireMock- Mocking the GET endpoint -done- *****");
             }
             else if("POST".equals(mockStep.getOperation())){
-                givenThat(WireMock.post(urlEqualTo(mockStep.getUrl()))
-                        .willReturn(aResponse()
-                                .withStatus(mockStep.getResponse().get("status").asInt())
-                                .withHeader("Content-Type", APPLICATION_JSON)
-                                .withBody(jsonBodyRequest)));
+                LOGGER.info("*****WireMock- Mocking the POST endpoint");
+                givenThat(createPostRequestBuilder(mockStep)
+                        .willReturn(responseBuilder(mockStep, jsonBodyRequest)));
+                LOGGER.info("WireMock- Mocking the POST endpoint -done-*****");
             }
             else if("PUT".equals(mockStep.getOperation())){
-                givenThat(WireMock.put(urlEqualTo(mockStep.getUrl()))
-                        .willReturn(aResponse()
-                                .withStatus(mockStep.getResponse().get("status").asInt())
-                                .withHeader("Content-Type", APPLICATION_JSON)
-                                .withBody(jsonBodyRequest)));
+                LOGGER.info("*****WireMock- Mocking the PUT endpoint");
+                givenThat(createPutRequestBuilder(mockStep)
+                        .willReturn(responseBuilder(mockStep, jsonBodyRequest)));
+                LOGGER.info("WireMock- Mocking the PUT endpoint -done-*****");
             }
         });
     }
 
+
+    public static void restartWireMock(int dynamicPort) {
+        wireMockServer = new WireMockServer(wireMockConfig().port(dynamicPort)); // <-- Strange
+        /*
+         * Stop the wireMock server if it is running previously due to any other tests.
+         */
+        wireMockServer.stop();
+        wireMockServer.start();
+        WireMock.configureFor("localhost", dynamicPort); // <-- Repetition of PORT was needed, this is a wireMock bug
+    }
+
+    private static MappingBuilder createPutRequestBuilder(MockStep mockStep) {
+        final MappingBuilder requestBuilder = put(urlEqualTo(mockStep.getUrl()));
+        return createRequestBuilderWithHeaders(mockStep, requestBuilder);
+    }
+
+    private static MappingBuilder createPostRequestBuilder(MockStep mockStep) {
+        final MappingBuilder requestBuilder = post(urlEqualTo(mockStep.getUrl()));
+        return createRequestBuilderWithHeaders(mockStep, requestBuilder);
+    }
+
+    private static MappingBuilder createGetRequestBuilder(MockStep mockStep) {
+        final MappingBuilder requestBuilder = get(urlEqualTo(mockStep.getUrl()));
+        return createRequestBuilderWithHeaders(mockStep, requestBuilder);
+    }
+
+    private static MappingBuilder createRequestBuilderWithHeaders(MockStep mockStep, MappingBuilder requestBuilder) {
+
+        final String bodyJson = mockStep.getBody();
+        // -----------------------------------------------
+        // read request body and set to request builder
+        // -----------------------------------------------
+        if(StringUtils.isNotEmpty(bodyJson)){
+            requestBuilder.withRequestBody(equalToJson(bodyJson));
+        }
+
+        final Map<String, Object> headersMap = mockStep.getHeadersMap();
+        // -----------------------------------------------
+        // read request headers and set to request builder
+        // -----------------------------------------------
+        if (headersMap.size() > 0) {
+            for (Object key : headersMap.keySet()) {
+                requestBuilder.withHeader((String) key, equalTo((String) headersMap.get(key)));
+            }
+        }
+        return requestBuilder;
+    }
+
+    private static ResponseDefinitionBuilder responseBuilder(MockStep mockStep, String jsonBodyRequest) {
+        final ResponseDefinitionBuilder responseBuilder = aResponse()
+                .withStatus(mockStep.getResponse().get("status").asInt())
+                //.withHeader("Content-Type", APPLICATION_JSON) //Can be XMl also for SOAP end points
+                .withBody(jsonBodyRequest);
+
+        return responseBuilder;
+    }
+
+
     /*
      * This is working code, whenever you put the virtuoso dependency here, you can uncomment this block.
      */
diff --git a/src/main/java/org/jsmart/zerocode/core/runner/ZeroCodeMultiStepsScenarioRunnerImpl.java b/src/main/java/org/jsmart/zerocode/core/runner/ZeroCodeMultiStepsScenarioRunnerImpl.java
index ee6335f4..7a3699b2 100644
--- a/src/main/java/org/jsmart/zerocode/core/runner/ZeroCodeMultiStepsScenarioRunnerImpl.java
+++ b/src/main/java/org/jsmart/zerocode/core/runner/ZeroCodeMultiStepsScenarioRunnerImpl.java
@@ -27,6 +27,7 @@ import java.util.function.BiConsumer;
 
 import static org.apache.commons.lang.StringUtils.isEmpty;
 import static org.jsmart.zerocode.core.domain.builders.ZeroCodeExecResultBuilder.newInstance;
+import static org.jsmart.zerocode.core.engine.mocker.RestEndPointMocker.wireMockServer;
 import static org.jsmart.zerocode.core.utils.SmartUtils.prettyPrintJson;
 import static org.slf4j.LoggerFactory.getLogger;
 
@@ -290,6 +291,12 @@ public class ZeroCodeMultiStepsScenarioRunnerImpl implements ZeroCodeMultiStepsS
 
         } //<-- Scenario Loop
 
+        /*
+         * Completed executing all steps?
+         * Then stop the wiremock server, so that its ready for next scenario.
+         */
+        stopWireMockServer();
+
         reportBuilder.printToFile(scenario.getScenarioName() + ".json");
 
         /*
@@ -346,4 +353,12 @@ public class ZeroCodeMultiStepsScenarioRunnerImpl implements ZeroCodeMultiStepsS
         
         return serviceType;
     }
+
+    private void stopWireMockServer() {
+        if (null != wireMockServer) {
+            wireMockServer.stop();
+            wireMockServer = null;
+            LOGGER.info("Scenario: All mockings done via WireMock server. Dependant end points executed. Stopped WireMock.");
+        }
+    }
 }


Test patch:
diff --git a/src/test/java/org/jsmart/zerocode/core/domain/MockStepTest.java b/src/test/java/org/jsmart/zerocode/core/domain/MockStepTest.java
new file mode 100644
index 00000000..525e73fc
--- /dev/null
+++ b/src/test/java/org/jsmart/zerocode/core/domain/MockStepTest.java
@@ -0,0 +1,66 @@
+package org.jsmart.zerocode.core.domain;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.jsmart.zerocode.core.di.ObjectMapperProvider;
+import org.jsmart.zerocode.core.utils.SmartUtils;
+import org.junit.Test;
+
+import java.util.HashMap;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+/**
+ * See also:
+ * RestEndPointMockerTest.java - for integration tests.
+ *
+ */
+public class MockStepTest {
+
+    private ObjectMapper objectMapper = new ObjectMapperProvider().get();
+
+    @Test
+    public void testSerDeSer() throws Exception {
+        final String aMock = SmartUtils.readJsonAsString("wiremock/test_mock_step.json");
+
+        final MockStep mockStep = objectMapper.readValue(aMock, MockStep.class);
+
+        assertThat(mockStep.getOperation(), is("GET"));
+        assertThat(mockStep.getResponse().get("status").asInt(), is(200));
+        assertThat(mockStep.getResponse().get("status").intValue(), is(200));
+        assertThat(mockStep.getResponse().get("status").toString(), is("200"));
+
+    }
+
+    @Test
+    public void testSerDeSer_headers() throws Exception {
+        final String aMock = SmartUtils.readJsonAsString("wiremock/test_mock_step_request_headers.json");
+
+        final MockStep mockStep = objectMapper.readValue(aMock, MockStep.class);
+
+        assertThat(mockStep.getOperation(), is("GET"));
+        assertThat(mockStep.getRequest().get("headers").toString(), is("{\"key\":\"key-001\",\"secret\":\"secret-001\"}"));
+
+        HashMap<String,Object> headersMap = (HashMap<String,Object>)objectMapper.readValue(mockStep.getRequest().get("headers").toString(), HashMap.class);
+        assertThat(headersMap.get("key"), is("key-001"));
+        assertThat(headersMap.get("secret"), is("secret-001"));
+
+    }
+
+    @Test
+    public void testSerDeSer_body() throws Exception {
+        final String aMock = SmartUtils.readJsonAsString("wiremock/test_mock_step_request_body.json");
+
+        final MockStep mockStep = objectMapper.readValue(aMock, MockStep.class);
+
+        assertThat(mockStep.getOperation(), is("GET"));
+        assertThat(mockStep.getRequest().get("body").toString(),
+                is("{\"name\":\"Emma\",\"age\":33,\"address\":{\"line1\":\"address line 1\",\"line2\":\"address line 2\"}}"));
+
+        // The followings are not needed as WireMock will accept the full JSON body as it is
+        HashMap<String,Object> bodyAsMap = (HashMap<String,Object>)objectMapper.readValue(mockStep.getRequest().get("body").toString(), HashMap.class);
+        assertThat(bodyAsMap.get("name"), is("Emma"));
+        assertThat(((HashMap)bodyAsMap.get("address")).get("line1"), is("address line 1"));
+
+    }
+}
\ No newline at end of file
diff --git a/src/test/java/org/jsmart/zerocode/core/engine/mocker/RestEndPointMockerTest.java b/src/test/java/org/jsmart/zerocode/core/engine/mocker/RestEndPointMockerTest.java
index 3cd841bf..acde9320 100644
--- a/src/test/java/org/jsmart/zerocode/core/engine/mocker/RestEndPointMockerTest.java
+++ b/src/test/java/org/jsmart/zerocode/core/engine/mocker/RestEndPointMockerTest.java
@@ -2,8 +2,16 @@ package org.jsmart.zerocode.core.engine.mocker;
 
 
 import com.fasterxml.jackson.databind.ObjectMapper;
+import com.github.tomakehurst.wiremock.client.MappingBuilder;
 import com.github.tomakehurst.wiremock.client.WireMock;
 import com.github.tomakehurst.wiremock.junit.WireMockRule;
+import org.apache.commons.io.IOUtils;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
 import org.jboss.resteasy.client.ClientRequest;
 import org.jboss.resteasy.client.ClientResponse;
 import org.jboss.resteasy.client.core.executors.ApacheHttpClientExecutor;
@@ -22,8 +30,15 @@ import org.skyscreamer.jsonassert.JSONAssert;
 
 import javax.inject.Inject;
 
+import java.util.Map;
+
 import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
+import static com.github.tomakehurst.wiremock.client.WireMock.equalTo;
+import static com.github.tomakehurst.wiremock.client.WireMock.equalToJson;
+import static com.github.tomakehurst.wiremock.client.WireMock.get;
 import static com.github.tomakehurst.wiremock.client.WireMock.givenThat;
+import static com.github.tomakehurst.wiremock.client.WireMock.post;
+import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
 import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
 import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
 import static org.hamcrest.CoreMatchers.containsString;
@@ -33,6 +48,7 @@ import static org.hamcrest.MatcherAssert.assertThat;
 
 @RunWith(JukitoRunner.class)
 public class RestEndPointMockerTest {
+
     public static class JukitoModule extends TestModule {
         @Override
         protected void configureTest() {
@@ -47,7 +63,7 @@ public class RestEndPointMockerTest {
     SmartUtils smartUtils;
 
     @Inject
-    private ObjectMapper mapper;
+    private ObjectMapper objectMapper;
 
     RestEndPointMocker restEndPointMocker;
 
@@ -60,8 +76,8 @@ public class RestEndPointMockerTest {
 
     @Test
     public void willDeserializeA_VanilaFlow() throws Exception {
-        String jsonDocumentAsString = smartUtils.getJsonDocumentAsString("10_mocking_endpoints/01_wire_mock_end_point_will_respond_to_get_call.json");
-        ScenarioSpec flowDeserialized = mapper.readValue(jsonDocumentAsString, ScenarioSpec.class);
+        String jsonDocumentAsString = smartUtils.getJsonDocumentAsString("wiremock_integration/01_wire_mock_end_point_will_respond_to_get_call.json");
+        ScenarioSpec flowDeserialized = objectMapper.readValue(jsonDocumentAsString, ScenarioSpec.class);
 
         assertThat(flowDeserialized, notNullValue());
         assertThat(flowDeserialized.getSteps().size(), is(1));
@@ -96,15 +112,15 @@ public class RestEndPointMockerTest {
         // WireMock wireMock = new WireMock(9073);
         // WireMock.configureFor(9073);
 
-        String jsonDocumentAsString = smartUtils.getJsonDocumentAsString("10_mocking_endpoints/01_wire_mock_end_point_will_respond_to_get_call.json");
-        ScenarioSpec flowDeserialized = mapper.readValue(jsonDocumentAsString, ScenarioSpec.class);
+        String jsonDocumentAsString = smartUtils.getJsonDocumentAsString("wiremock_integration/01_wire_mock_end_point_will_respond_to_get_call.json");
+        ScenarioSpec flowDeserialized = objectMapper.readValue(jsonDocumentAsString, ScenarioSpec.class);
         MockSteps mockSteps = smartUtils.getMapper().readValue(flowDeserialized.getSteps().get(0).getRequest().toString(), MockSteps.class);
 
         final MockStep mockStep = mockSteps.getMocks().get(0);
         String jsonBodyRequest = mockStep.getResponse().get("body").toString();
 
         WireMock.configureFor(9073);
-        givenThat(WireMock.get(urlEqualTo(mockStep.getUrl()))
+        givenThat(get(urlEqualTo(mockStep.getUrl()))
                 .willReturn(aResponse()
                         .withStatus(mockStep.getResponse().get("status").asInt())
                         .withHeader("Content-Type", APPLICATION_JSON)
@@ -119,6 +135,84 @@ public class RestEndPointMockerTest {
         JSONAssert.assertEquals(jsonBodyRequest, respBodyAsString, true);
 
         System.out.println("### zerocode: \n" + respBodyAsString);
+
+    }
+
+    @Test
+    public void willMockAPostRequest() throws Exception{
+
+        WireMock.configureFor(9073);
+
+        String jsonDocumentAsString = smartUtils.getJsonDocumentAsString("wiremock_integration/01_wire_mock_end_point_will_respond_to_get_call.json");
+        ScenarioSpec flowDeserialized = objectMapper.readValue(jsonDocumentAsString, ScenarioSpec.class);
+        MockSteps mockSteps = smartUtils.getMapper().readValue(flowDeserialized.getSteps().get(0).getRequest().toString(), MockSteps.class);
+
+        final MockStep mockPost = mockSteps.getMocks().get(1);
+        String jsonBodyResponse = mockPost.getResponse().get("body").toString();
+
+        final String bodyJson = mockPost.getRequest().get("body").toString(); //"{ \"id\" : \"p002\" }";
+        stubFor(post(urlEqualTo(mockPost.getUrl()))
+                .withRequestBody(equalToJson(bodyJson))
+                .willReturn(aResponse()
+                        .withStatus(mockPost.getResponse().get("status").asInt())
+                        .withHeader("Content-Type", APPLICATION_JSON)
+                        .withBody(jsonBodyResponse)));
+
+        CloseableHttpClient httpClient = HttpClients.createDefault();
+        HttpPost request = new HttpPost("http://localhost:9073" + mockPost.getUrl());
+        request.addHeader("Content-Type", "application/json");
+        StringEntity entity = new StringEntity(bodyJson);
+        request.setEntity(entity);
+        HttpResponse response = httpClient.execute(request);
+
+        final String responseBodyActual = IOUtils.toString(response.getEntity().getContent(), "UTF-8");
+        System.out.println("### response: \n" + responseBodyActual);
+
+        assertThat(response.getStatusLine().getStatusCode(), is(201));
+        JSONAssert.assertEquals(jsonBodyResponse, responseBodyActual, true);
+
     }
 
+    @Test
+    public void willMockAGetRequestWith_headers() throws Exception{
+
+        WireMock.configureFor(9073);
+
+        String jsonDocumentAsString = smartUtils.getJsonDocumentAsString("wiremock_integration/01_wire_mock_end_point_will_respond_to_get_call.json");
+        ScenarioSpec flowDeserialized = objectMapper.readValue(jsonDocumentAsString, ScenarioSpec.class);
+        MockSteps mockSteps = smartUtils.getMapper().readValue(flowDeserialized.getSteps().get(0).getRequest().toString(), MockSteps.class);
+
+        final MockStep mockGetStep = mockSteps.getMocks().get(0);
+        final Map<String, Object> headersMap = mockGetStep.getHeadersMap();
+
+        final MappingBuilder requestBuilder = get(urlEqualTo(mockGetStep.getUrl()));
+
+        // read request headers and set to request builder
+        if (headersMap.size() > 0) {
+            for (Object key : headersMap.keySet()) {
+                requestBuilder.withHeader((String) key, equalTo((String) headersMap.get(key)));
+            }
+        }
+
+        String jsonBodyResponse = mockGetStep.getResponse().get("body").toString();
+
+        stubFor(requestBuilder
+                .willReturn(aResponse()
+                        .withStatus(mockGetStep.getResponse().get("status").asInt())
+                        //.withHeader("Content-Type", APPLICATION_JSON)
+                        .withBody(jsonBodyResponse)));
+
+        CloseableHttpClient httpClient = HttpClients.createDefault();
+        HttpGet request = new HttpGet("http://localhost:9073" + mockGetStep.getUrl());
+        request.addHeader("key", "key-007");
+        request.addHeader("secret", "secret-007");
+
+        HttpResponse response = httpClient.execute(request);
+        final String responseBodyActual = IOUtils.toString(response.getEntity().getContent(), "UTF-8");
+        System.out.println("### response: \n" + responseBodyActual);
+
+        assertThat(response.getStatusLine().getStatusCode(), is(200));
+        JSONAssert.assertEquals(jsonBodyResponse, responseBodyActual, true);
+
+    }
 }
\ No newline at end of file
diff --git a/src/test/java/org/jsmart/zerocode/wiremock/WireMockIntegrationTest.java b/src/test/java/org/jsmart/zerocode/wiremock/WireMockIntegrationTest.java
new file mode 100644
index 00000000..e11712fc
--- /dev/null
+++ b/src/test/java/org/jsmart/zerocode/wiremock/WireMockIntegrationTest.java
@@ -0,0 +1,19 @@
+package org.jsmart.zerocode.wiremock;
+
+import org.jsmart.zerocode.core.domain.JsonTestCase;
+import org.jsmart.zerocode.core.domain.TargetEnv;
+import org.jsmart.zerocode.core.runner.ZeroCodeUnitRunner;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@TargetEnv("web_app.properties")
+@RunWith(ZeroCodeUnitRunner.class)
+public class WireMockIntegrationTest {
+
+    @Test
+    @JsonTestCase("wiremock_integration/mock_via_wiremock_then_test_the_end_point.json")
+    public void testWireMock() throws Exception {
+
+    }
+}
+
diff --git a/src/test/resources/10_mocking_endpoints/01_wire_mock_end_point_will_respond_to_get_call.json b/src/test/resources/10_mocking_endpoints/01_wire_mock_end_point_will_respond_to_get_call.json
deleted file mode 100644
index 41acd4c7..00000000
--- a/src/test/resources/10_mocking_endpoints/01_wire_mock_end_point_will_respond_to_get_call.json
+++ /dev/null
@@ -1,45 +0,0 @@
-{
-  "scenarioName": "create_mocks", //<-- comments allowed
-  "steps": [
-    {
-      "name": "GetBathRoomDetails",
-      "url": "/$MOCK",
-      "operation": "$USE.WIREMOCK",
-      "request": {
-        "mocks":[
-          {
-            "name": "Mock the Get Person",
-            "operation": "GET",
-            "url": "/google-guys/persons/p001",
-            "response": {
-              "status": 200,
-              "body": {
-                "id": "p001",
-                "source": {
-                  "code": "GOOGLE.UK"
-                }
-              }
-            }
-          },
-          {
-            "name": "Mock the POST Person",
-            "operation": "POST",
-            "url": "/google-guys/persons/p002",
-            "response": {
-              "status": 201,
-              "body": {
-                "id": "p002",
-                "source": {
-                  "code": "GOOGLE.IN"
-                }
-              }
-            }
-          }
-        ]
-      },
-      "assertions": {
-        "status": 200
-      }
-    }
-  ]
-}
diff --git a/src/test/resources/web_app.properties b/src/test/resources/web_app.properties
new file mode 100644
index 00000000..0230e83d
--- /dev/null
+++ b/src/test/resources/web_app.properties
@@ -0,0 +1,9 @@
+# Web Server host and port
+restful.application.endpoint.host=http://localhost
+restful.application.endpoint.port=8888
+
+# Web Service context; Leave it blank in case you do not have a common context
+restful.application.endpoint.context=
+
+# WireMock will use this port for mocking dependent end points
+mock.api.port=8888
\ No newline at end of file
diff --git a/src/test/resources/wiremock/test_mock_step.json b/src/test/resources/wiremock/test_mock_step.json
new file mode 100644
index 00000000..83462fd5
--- /dev/null
+++ b/src/test/resources/wiremock/test_mock_step.json
@@ -0,0 +1,14 @@
+{
+    "name": "Mock the Get Person",
+    "operation": "GET",
+    "url": "/google-guys/persons/p001",
+    "response": {
+        "status": 200,
+        "body": {
+            "id": "p001",
+            "source": {
+                "code": "GOOGLE.UK"
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/test/resources/wiremock/test_mock_step_request_body.json b/src/test/resources/wiremock/test_mock_step_request_body.json
new file mode 100644
index 00000000..24ff05d6
--- /dev/null
+++ b/src/test/resources/wiremock/test_mock_step_request_body.json
@@ -0,0 +1,24 @@
+{
+    "name": "Mock the Get Person With Request Body",
+    "operation": "GET",
+    "url": "/google-guys/persons/p001",
+    "request": {
+        "body": {
+            "name": "Emma",
+            "age": 33,
+            "address": {
+                "line1": "address line 1",
+                "line2": "address line 2"
+            }
+        }
+    },
+    "response": {
+        "status": 200,
+        "body": {
+            "id": "p001",
+            "source": {
+                "code": "GOOGLE.UK"
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/test/resources/wiremock/test_mock_step_request_headers.json b/src/test/resources/wiremock/test_mock_step_request_headers.json
new file mode 100644
index 00000000..06f6d175
--- /dev/null
+++ b/src/test/resources/wiremock/test_mock_step_request_headers.json
@@ -0,0 +1,20 @@
+{
+    "name": "Mock the Get Person With Request Headers",
+    "operation": "GET",
+    "url": "/google-guys/persons/p001",
+    "request" : {
+        "headers":{
+            "key": "key-001",
+            "secret": "secret-001"
+        }
+    },
+    "response": {
+        "status": 200,
+        "body": {
+            "id": "p001",
+            "source": {
+                "code": "GOOGLE.UK"
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/test/resources/wiremock_integration/01_wire_mock_end_point_will_respond_to_get_call.json b/src/test/resources/wiremock_integration/01_wire_mock_end_point_will_respond_to_get_call.json
new file mode 100644
index 00000000..04e95b2a
--- /dev/null
+++ b/src/test/resources/wiremock_integration/01_wire_mock_end_point_will_respond_to_get_call.json
@@ -0,0 +1,56 @@
+{
+    "scenarioName": "create_mocks",
+    "steps": [
+        {
+            "name": "GetBathRoomDetails",
+            "url": "/$MOCK",
+            "operation": "$USE.WIREMOCK",
+            "request": {
+                "mocks": [
+                    {
+                        "name": "Mock the Get Person",
+                        "operation": "GET",
+                        "url": "/google-guys/persons/p001",
+                        "request": {
+                            "headers": {
+                                "key": "key-007",
+                                "secret": "secret-007"
+                            }
+                        },
+                        "response": {
+                            "status": 200,
+                            "body": {
+                                "id": "p001",
+                                "source": {
+                                    "code": "GOOGLE.UK"
+                                }
+                            }
+                        }
+                    },
+                    {
+                        "name": "Mock the POST Person",
+                        "operation": "POST",
+                        "url": "/google-guys/persons/p002",
+                        "request": {
+                            "body":{
+                                "id": "p002"
+                            }
+                        },
+                        "response": {
+                            "status": 201,
+                            "body": {
+                                "id": "p002",
+                                "source": {
+                                    "code": "GOOGLE.IN"
+                                }
+                            }
+                        }
+                    }
+                ]
+            },
+            "assertions": {
+                "status": 200
+            }
+        }
+    ]
+}
diff --git a/src/test/resources/wiremock_integration/mock_via_wiremock_then_test_the_end_point.json b/src/test/resources/wiremock_integration/mock_via_wiremock_then_test_the_end_point.json
new file mode 100644
index 00000000..4c13ca6b
--- /dev/null
+++ b/src/test/resources/wiremock_integration/mock_via_wiremock_then_test_the_end_point.json
@@ -0,0 +1,72 @@
+{
+    "scenarioName": "Will Mock some End Points via WireMock and Test the end points using Zerocode",
+    "steps": [
+        {
+            "name": "setup_mocks",
+            "url": "/$MOCK",
+            "operation": "$USE.WIREMOCK",
+            "request": {
+                "mocks": [
+                    {
+                        "name": "mocking_a_GET_endpoint_with_headers",
+                        "operation": "GET",
+                        "url": "/api/v1/amazon/customers/cust-007",
+                        "request": {
+                            "headers": {
+                                "api_key": "key-01-01",
+                                "api_secret": "secret-01-01"
+                            }
+                        },
+                        "response": {
+                            "status": 200,
+                            "body": {
+                                "id": "cust-007",
+                                "type": "Premium"
+                            }
+                        }
+                    }
+                ]
+            },
+            "assertions": {
+                "status": 200
+            }
+        },
+        //------------- Mocking done at this point via WireMock ---------------
+
+        //------------- Let's verify the end points by writing the following small tests ------------
+        {
+            "name": "verify_get_customer_with_headers",
+            "url": "/api/v1/amazon/customers/cust-007",
+            "operation": "GET",
+            "request": {
+                "headers": {
+                    "api_key": "key-01-01", //<--- Please try with a wrong key. The test should fail.
+                    "api_secret": "secret-01-01"
+                }
+            },
+            "assertions": {
+                "status": 200,
+                "body": {
+                    "id": "cust-007",
+                    "type": "Premium"
+                }
+            }
+        },
+        {
+            "name": "verify_get_customer_without_headers",
+            "url": "/api/v1/amazon/customers/cust-007",
+            "operation": "GET",
+            "request": {
+                "headers": {
+                    //"api_key": "key-01-01", //<--- Please try with a wrong key. The test should fail.
+                    "api_secret": "secret-01-01"
+                }
+            },
+            "assertions": {
+                "status" : 404,
+                "rawBody" : "$CONTAINS.STRING:HTTP ERROR 404"
+            }
+        }
+
+    ]
+}