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
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/