我使用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是否提供类似的东西,或者我需要手动制作。
答案 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-databind和junit进行精确比较非常简单。
我们应该编写一个函数,将由保证对象返回的主体与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);