Search code examples
junitspring-boot-testwiremockwiremock-standalonewiremock-record

WireMock - How to Include Request JSON Body Into the Response Body?


What I have achieved so far?

I'm using WireMock with Spring Boot Application using the JUNIT 5.

I am stubbing the test endpoint with the custom Request and Response JSON payload:

REQUEST PAYLOAD:

{
    "merchantId": "xxxx",
    "data": [
        {
            "id": "unique-id-1",
            "sensitiveData": "xxxxxx",
        },
      ...
      ...
   ]
}

RESPONSE PAYLOAD:

{
    "status": "SUCCESS",
    "tokens": [
        {
            "id": "unique-id-1",
            "token": "xxxxxxxxxx",
        },
           ...
           ...  

   ]
}

What I'm trying to achieve?

Since my JSON Request payload is dynamic. I want to create a dynamic JSON Payload in response as well where tokens values in JSON are static but the id's value in JSON is dynamic based on the request payload's id value.
@SpringBatchTest
class FileTest{
   private WireMockServer wireMockServer;

   BeforeEach
   void setUp() {
       wireMockServer =
         new WireMockServer(options().extensions(new          
             ResponseTemplateTransformer(true)).port(PORT));

       WireMock.configureFor("localhost", PORT);
       wireMockServer.start();
  }

  @AfterEach
  void tearDown() {
       wireMockServer.stop();
  

@Test
  void testEndToEndFlowForSpringBatch() {
       final String body = ResponsePayload.getResponseJsonPayload();
       wireMockServer.addStubMapping(
        stubFor(
            post(urlPathMatching("/test"))
                .willReturn(
                    aResponse()
                        .withBody(body)
                        .withStatus(200)
                        .withTransformers("response-template"))));
       //morecode
}

ResponsePayload.getResponseJsonPayload() contains below value:
{
    "response": "SUCCESS",
    "tokens": [
        {
            "id": "{{jsonPath request.body '$.data[0].id'}}",
            "token": "xxxxxx",
        },
        {
            "id": "{{jsonPath request.body '$.data[1].id'}}",
            "token": "xxxxxxx",
        },
                  ..
    ]
}

What is not working?

When I am debugging the program I can see the stub is throwing following error:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=ISO-8859-1"/>
<title>Error 500 </title>
</head>
<body>
<h2>HTTP ERROR: 500</h2>
<p>Problem accessing /test. Reason:
<pre>    wiremock.com.github.jknack.handlebars.HandlebarsException: inline@1e0c0274:5:21: could not find helper: &apos;jsonPath&apos;
            &quot;id&quot;: &quot;{{jsonPath request.body &apos;$.merchantId&apos;}}&quot;,
                     ^
</pre></p>
<hr /><i><small>Powered by Jetty://</small></i>
</body>
</html>

I've already read below answers but couldn't find a way of using the jsonPath:

Any help would be appreciable.

Thanks!


Solution

  • All I needed to fix the issue was to upgrade the version of WireMock from <version>2.6.0</version> to the latest one <version>3.0.0-beta-9</version>.

    Dependency:

    <dependency>
        <groupId>com.github.tomakehurst</groupId>
        <artifactId>wiremock-standalone</artifactId>
        <version>3.0.0-beta-9</version>
        <scope>test</scope>
    </dependency>
    

    You can get the latest one from the Maven store here: Maven Store

    Also, create the server this way:

    private WireMockServer wireMockServer;
    
    @BeforeEach
    void setUp() {
        wireMockServer =
            new WireMockServer(
                    options()
                    .extensions(new ResponseTemplateTransformer(true))
                    .port(PORT));
    
        wireMockServer.start();
    }
    

    And in the stub:

    @Test
    void testWireMockServerIsUp() {
        wireMockServer.stubFor(
            post(urlPathMatching("/test"))
                .willReturn(
                    aResponse().withBody(body).withStatus(200)));
    }