Full Json match with RestAssured

2019-06-22 13:24发布

问题:

I'm using REST-Assured to test some API. My API clearly respond with a JSON and according to the doc if this is the response:

{
    "id": "390",
    "data": {
        "leagueId": 35,
        "homeTeam": "Norway",
        "visitingTeam": "England",
    },
    "odds": [{
        "price": "1.30",
        "name": "1"
    },
    {
        "price": "5.25",
        "name": "X"
    }]
}

I could test like this:

@Test
public void givenUrl_whenSuccessOnGetsResponseAndJsonHasRequiredKV_thenCorrect() {
   get("/events?id=390")
      .then()
         .statusCode(200)
         .assertThat()
            .body("data.leagueId", equalTo(35)); 
}

Surely this is readable but I would a full comparison of the JSON (i.e.: this is the JSON response; this is a canned JSON - a resource file would be perfect - are those JSON equals?). Does REST-Assured offer something like that or I need to make it manually.

回答1:

I had the same problem, and resolved it with RestAssured's JsonPath to parse the json file into a Map and then compare it with Hamcrest Matchers. This way the order etc didn't matter.

import static org.hamcrest.Matchers.equalTo;
import io.restassured.path.json.JsonPath;

...

JsonPath expectedJson = new JsonPath(new File("/path/to/expected.json"));

given()
    ...
    .then()
    .body("", equalTo(expectedJson.getMap("")));


回答2:

Karate is exactly what you are looking for - you can perform a full equality match of a JSON payload in one step.

And for the cases where you have dynamic values (generated keys, timestamps) Karate provides a very elegant way for you to ignore (or just validate the format of) these keys.

One the primary motivations for creating Karate was to come up with a better alternative to REST-assured. You can refer to this document which can help you evaluate Karate and make a case for it in your organization: Karate vs REST-assured.



回答3:

Easy way:

String s = "{\"ip\": \"your_ip\"}";
given().log().all().contentType(ContentType.JSON).get("http://ip.jsontest.com/").then().log().all().assertThat().body(containsString(s))

Not easy way: you can create custom matcher or use jsonpath, it has options to comapre jsons.



回答4:

REST Assured does not support JSON comparison, only schema and parts of the body as you have in your question. What you can do is using Hamcrest's JSON comparitorSameJSONAs in Hamcrest JSON SameJSONAs