I am trying to use custom helpers to convert a list of Query Parameters form a request to a JSON response. The request is something like /scores?userIds=1&userIds=2
and my desired response is a list of JSON objects like the following:
[
{
"userId": 1,
"score": 80
},
{
"userId": 2,
"score": 200
}
]
To do so, I have implemented a helper called userScoreHelper
:
Helper<List<String>> userScoreHelper = (context, options) -> {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("[");
context.forEach(element ->
stringBuilder
.append("{\"score\": ")
.append(RandomGeneratorUtility.generateRandomNumber(0, 700) - 1)
.append(",\"userId\": ")
.append(element)
.append("},")
);
stringBuilder
.deleteCharAt(stringBuilder.lastIndexOf(","))
.append("]");
log.debug("Json response: {}", stringBuilder.toString());
return stringBuilder.toString();
};
And then I registered the helper in my WireMockServer
configuration as follows:
@Bean(initMethod = "start", destroyMethod = "stop")
@Rule
public WireMockServer mockServer() {
return new WireMockServer(
options()
.port(9561)
.extensions(new ResponseTemplateTransformer(false,
"user-score-helper",
userScoreHelper))
);
}
The configuration of my stub looks like this:
public class ScoringCommunicatorMocks {
public static void setupMockScoringCommunicatorResponse(WireMockServer mockService) {
mockService.stubFor(
WireMock.get(WireMock.urlPathEqualTo("/scores"))
.willReturn(WireMock.aResponse()
//Using the registered handlebars helper here
.withBody("{{user-score-helper request.query.userIds}}")
.withHeader("Content-Type", "application/json")
.withStatus(200)
.withTransformers("response-template"))
);
}
}
And the output of the helper is a valid JSON according to my debugging logs, something like this:
[{"score": 304,"userId": 10},{"score": 28,"userId": 20}]
But when I try to run my unit tests I am getting an error message from JSON Decoder stating that my response contains an unexpected '&' character.
feign.codec.DecodeException: JSON conversion problem: Unexpected character ('&' (code 38)): was expecting double-quote to start field name; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Unexpected character ('&' (code 38)): was expecting double-quote to start field name
at [Source: (PushbackInputStream); line: 1, column: 2] (through reference chain: java.util.ArrayList[0])
I suspect the WireMock is having problem with escaped " character because if I put the generated JSON object directly in the body like this .withBody("[{\"score\": 304,\"userId\": 10},{\"score\": 28,\"userId\": 20}]")
it just works perfectly.
This is an awfully strange behavior and I have no clue how to get deeper at the root cause of this error (the rest of the stacktrace is irrelevant and adds nothing useful to what I have already stated here).
Any pointers or solutions are greatly appreciated.
I have actually managed to figure out what was wrong when I finished writing the question. It was indeed the the problem with escaping characters, all I needed to do was to use the "triple-mustaches" or "triple-stash" when I am calling the helper .withBody("{{{user-score-helper request.query.userIds}}}")
instead of .withBody("{{user-score-helper request.query.userIds}}")