Search code examples
javajsonpathwiremock

wiremock jsonPath and int values


I'm Evaluating the Wiremock to be used in our project

Need help in understanding how to generate the integer field in the response taken out of request (both are JSONs). Example of stub mappings:

String mapping = """
            {
              'request': {
                'method': 'POST',
                'urlPathTemplate': '/v1/persons/{personId}'
              },
                        
              'response': {
                'status': 200,
                'jsonBody':  {
                    'name' : "{{jsonPath request.body '$.name'}}",
                    'age' : "{{jsonPath request.body '$.age'}}",
                    'id' :  '{{request.path.personId}}'
                 },
                'headers': {
                    'Content-Type': 'application/json'
                }
              }
            }
            """;

So I expect to post the request to

POST: http://localhost:8080/v1/persons/123456789

BODY:

{
   'name' : 'Alice',
   'age'  : 25
}

And my response is expected to be:

{
   "name" : "Alice",
   "age"  : 25,
   "id"   : "123456789"
}

However, the actual response body I get is slightly different, age's value is of type string:

{
   "name" : "Alice",
   "age"  : "25",                    <-- This is not what I want
   "id"   : "123456789"
}

Here is the code I use (plain java + wiremock 3.9.1 - the last available at the moment):

 WireMockServer ws = new WireMockServer(
                wireMockConfig()
                        .port(8080)
                        .globalTemplating(true)
        );

        ws.addStubMapping(StubMapping.buildFrom(mapping)); // my mapping string defined above
        ws.start();
        var req = HttpRequest.newBuilder()
                .uri(new URI("http://localhost:8080/v1/persons/123456789"))
                .POST(HttpRequest.BodyPublishers.ofString("""
                        {
                          'name' : 'Alice',
                          'age' : 25
                        }
                        """)).build();
        var client = HttpClient.newHttpClient();
        var resp = client.send(req, HttpResponse.BodyHandlers.ofString());
        System.out.println("Got a body: " + resp.body());
        ws.shutdownServer();

I couldn't find a relevant example in the Wiremock documentation for this case, so I'm asking for help. Also is it possible to render the 'id' field as a number (probably the solution is similar), despite it was taken from the request path and not from the body


Solution

  • This is a symptom of using jsonBody and response templating in your stub definition. jsonBody is a nice convenient way of not having to escape your json like you do with the body element. However, the stub definition obviously has to be valid json which means you have to put quotes around the places you want to use the response templating otherwise the {{ would be flagged as invalid json. As you are seeing, this means your data comes out as strings because of the quotes surrounding the templated data.

    The only option you have here is to switch from using jsonBody to body or bodyFileName. Using the body element in your stub definition means you will have to escape your json and using bodyFileName means you can extract your body definition into a separate file.

    For example, the following shows your stub definition using the body element:

    {
      "request": {
        "method": "POST",
        "urlPathTemplate": "/v1/persons/{personId}"
      },
    
      "response": {
        "status": 200,
        "body": "{\"name\": \"{{jsonPath request.body '$.name'}}\",\"age\": {{jsonPath request.body '$.age'}},\"id\": {{request.path.personId}} }",
        "transformers": ["response-template"],
        "headers": {
          "Content-Type": "application/json"
        }
      }
    }
    

    This will produce the following result with the request you posted in your question:

    {
      "name": "Alice",
      "age": 25,
      "id": 123456789
    }
    

    More information on stubbing can be found here - https://wiremock.org/docs/stubbing/