完整的Json与RestAssured匹配

时间:2017-06-23 08:29:08

标签: json rest rest-assured

我使用REST-Assured来测试某些API。我的API明确地使用JSON进行响应,并根据文档回答是否为响应:

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

我可以这样测试:

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

当然这是可读的,但我会对JSON进行全面比较(即:这是JSON响应;这是一个罐装JSON - 资源文件是完美的 - 那些JSON等于吗?)。 REST-Assured是否提供类似的东西,或者我需要手动制作。

8 个答案:

答案 0 :(得分:1)

我遇到了同样的问题,并使用RestAssured的JsonPath解决了该问题,将json文件解析为Map,然后将其与Hamcrest Matchers进行了比较。这样,顺序等无所谓。

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("")));

答案 1 :(得分:0)

简单方法:

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

不容易的方法:你可以创建自定义匹配器或使用jsonpath,它有comapre jsons的选项。

答案 2 :(得分:0)

Karate正是您所寻找的 - 您可以一步完成JSON有效负载的完整相等匹配。

对于拥有动态值(生成的密钥,时间戳)的情况,Karate提供了一种非常优雅的方式来忽略(或只是验证这些密钥的格式)。

创建空手道的主要动机之一是提出一个更好的替代REST保证。您可以参考此文档,它可以帮助您评估空手道并在您的组织中为其提供案例:Karate vs REST-assured

答案 3 :(得分:0)

REST Assured不支持JSON比较,只支持您的问题中的架构和正文部分。您可以做的是在Hamcrest JSON SameJSONAs中使用Hamcrest的JSON comparitorSameJSONAs

答案 4 :(得分:0)

如果有人在寻找不解析json文件的方法。

您可以使用Matchers.aMapWithSize(size)开头来检查身体大小,然后照常检查内容。

示例:

@Test
public void getAccount_forbidden_whenUserIsAnonymous() {
    RestAssured
        .get("/account")
        .then()
        .statusCode(HttpServletResponse.SC_FORBIDDEN)
        .body("", Matchers.aMapWithSize(5),
              "timestamp", Matchers.notNullValue(),
              "status", Matchers.equalTo(HttpServletResponse.SC_FORBIDDEN),
              "error", Matchers.equalTo("Forbidden"),
              "message", Matchers.equalTo("Access Denied"),
              "path", Matchers.equalTo("/account"));
}

答案 5 :(得分:0)

显然,如here所述,放心只提供验证架构的功能。

但是,使用jackson-databindjunit进行精确比较非常简单。

我们应该编写一个函数,将由保证对象返回的主体与resources目录中的文件进行比较

import org.junit.Assert;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.json.JsonMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;

void assertJsonEquals(String expectedJson, ResponseBodyExtractionOptions actualBody) throws IOException {
    Assert.assertNotNull("The request returned no body", expectedJson);

    final ObjectMapper mapper = new ObjectMapper();
    Assert.assertEquals(
            mapper.readTree(Objects.requireNonNull(getClass().getClassLoader().getResource(expectedJsonPath)).openStream().readAllBytes()),
            mapper.readTree(body.asByteArray())
    );
}

然后,如下所示使用它

final ResponseBodyExtractionOptions actualBody = given()
        .accept("application/json")
        .contentType(MediaType.APPLICATION_JSON)
    .when()
        .get("...")
    .then()
        .extract().body();
assertJsonEquals("expected-payload.json", actualBody);

答案 6 :(得分:0)

您可以在RestAssured中使用Validate with JSON SCHEMA。

尝试以下代码:

//基础测试[BaseTest.java]

public class BaseTest {

    protected RequestSpecification requestSpecificationToMerge = new RequestSpecBuilder()
            .setBaseUri("BASE URL")
            .setContentType(ContentType.JSON)
            .build();

    @BeforeMethod
    public void setFilter() {
        RestAssured.filters(new AllureRestAssured());
    }

}

//测试[Home.java]

public class Home extends BaseTest {
    
    @Test(priority = 0)
    public void getHome() {
        
        given()
        .spec(requestSpecificationToMerge)
        .basePath("/your endpoint")
        .when()
        .get()
        .then()
        .log().body()
        .body(matchesJsonSchemaInClasspath("home.json"));
    }

// JSON SCHEMA [home.json]

{
    "type": "object",
    "required": [
        "data",
        "meta",
        "status"
    ],
    "properties": {
        "data": {
            "type": ["array", "null"],
            "items": {
                "type": "object",
                "required": [
                    "id",
                    "title",
                    "sorting"
                ],
                "properties": {
                    "id": {
                        "type": "integer"
                    },
                    "title": {
                        "type": "string"
                    },
                    "sorting": {
                        "type": "integer"
                    }
                }
            }
        },
        "meta": {
            "type": ["object", "null"],
            "required": [
                "pagination"
            ],
            "items": {
                "type": "object",
                "required": [
                    "current_page",
                    "per_page",
                    "total",
                    "total_page"
                ],
                "properties": {
                    "current_page": {
                        "type": "integer"
                    },
                    "per_page": {
                        "type": "integer"
                    },
                    "total": {
                        "type": "integer"
                    },
                    "total_page": {
                        "type": "integer"
                    }
                }
            }
        },
        "status": {
            "type": "object",
            "required": [
                "code",
                "message_client",
                "message_server"
            ],
            "properties": {
                "code": {
                    "type": "integer",
                    "enum": [
                        200,
                        404
                    ]
                },
                "message_client": {
                    "type": "string"
                },
                "message_server": {
                    "type": "string"
                }
            }
        }
    }
}

答案 7 :(得分:0)

您可以使用 JSONAssert 库来匹配整个 JSON 响应。 我最近写了一篇关于如何实现它的 blog。 你可能想看看它。

以下是关于如何使用库的基本用法:

    JSONAssert.assertEquals(expectedResponse, actualResponse, JSONCompareMode.LENIENT);