Check for null values in request body using Wiremock

血红的双手。 提交于 2021-02-17 02:04:52

问题


I am trying to setup a wiremock stub that will return a 400 error if any field has a null value in the json payload. Basically to simulate a Bad Request. I've been trying with a regex that matches any lowercase string for the json key but it doesn't seem to like it. I can't find any examples of what I want online so not sure if it's even possible.

My Bad Request body:

{
  "cat": null,
  "dog": {
    "id": 1344
},
  "horse": {
    "id": 1
},
  "fish": 1
}

My Stub:

wireMockServer.stubFor(post(urlEqualTo("/sample-api"))
            .withRequestBody(matchingJsonPath("$.^[a-z]*", equalTo(null)))
            .willReturn(aResponse()
                    .withStatus(400)
                    .withHeader("Content-Type", "application/json")))

In this example I would expect the stub to match "cat" as the value of it is null. This isn't the case. Can anyone tell me what I'm doing wrong?


回答1:


In the WireMock documentation on Request Matching the section on JSON Path matching. In the source code there is a reference to com.jayway.jsonpath.JsonPath library used. The build.gradle refers to version 2.4.0. The documentation for the Jayway JSON Path library can be found on their Github project page. There is a good, but by no means perfect online evaluator here.

The WireMock documentation only shows support for Regular Expression for the node values in the form of the "matchesJsonPath". In the Jayway documenatation there is an online example: $..book[?(@.author =~ /.*REES/i)]. For this reason the only approach is to name all the nodes that are not allowed to be null.

In the below example mapping all the mentioned nodes will be tested, regardless of their depth (see @id). This mapping will not trigger if all the mentioned nodes are not null, but some unmentioned ones are.

{
  "request": {
    "urlPattern": "/sample-api",
    "method": "GET",
    "bodyPatterns" : [ {
      "matchesJsonPath" : "$..[?(@.cat == null || @.dog == null || @.horse == null || @.fish == null || @.id == null)]"
    } ] 
  },
  "response": {
    "status": "400",
    "headers": {
      "Content-Type": "application/json; charset=utf-8"
    },
    "jsonBody": {
      "message": "some sapi message"
    }
  }
}



回答2:


If you weren't aware of all possible keys, you could use a Custom Request Matcher to check if the request body contained any null values, and if so, return your 400 error. I'd recommend creating your own class, something that resembles...

public class BodyNullCheck extends RequestMatcherExtension {
    @Override
    public MatchResult match(Request request, Parameters parameters) {
        JSONParser parser = new JSONParser();
        try {
            JSONObject body = (JSONObject) parser.parse(request.getBody().toString());
            for(Iterator iterator = body.keySet().iterator(); iterator.hasNext();) {
                String key = (String) iterator.next();
                if (body.get(key) == null) {
                    return MatchResult.of(true);
                }
            }
        } catch (ParseException ex) {
                ex.printStackTrace();
        }

        return MatchResult.of(false);
    }
}

The above takes the request body and converts it to a JSONObject, and then iterates over all keys in the JSONObject. If any of their values are null, then we will return true. If after iterating over all of them, a null value isn't found, we return false.



来源:https://stackoverflow.com/questions/59737299/check-for-null-values-in-request-body-using-wiremock

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!