How do we assert the JSON response field type?
{
"Data" : [
"Id" : 1,
"Name" : "ABC"
]
}
Is there any way to validate that ID
should contain an int
and Name
should be a String
? I don't want to validate the values.
How do we assert the JSON response field type?
{
"Data" : [
"Id" : 1,
"Name" : "ABC"
]
}
Is there any way to validate that ID
should contain an int
and Name
should be a String
? I don't want to validate the values.
You are asking how to check the JSON document structure.
JSON document validation against a JSON schema (JSON schema validation) is a way to perform such check.
Let's consider the following versions as the current versions:
5.1.1
.5.8.2
.REST Assured supports JSON schema validation.
The unit test class contain two tests: successful and failing.
The failing test fails with the following message:
java.lang.AssertionError: 1 expectation failed.
Response body doesn't match expectation.
Expected: The content to match the given JSON schema.
error: instance type (object) does not match any allowed primitive type (allowed: ["string"])
level: "error"
schema: {"loadingURI":"file:/<the-project-path>/target/test-classes/schema.json#","pointer":"/properties/Data/items/0/properties/Name"}
instance: {"pointer":"/Data/0/Name"}
domain: "validation"
keyword: "type"
found: "object"
expected: ["string"]
Actual: {
"Data": [
{
"Id": 1,
"Name": {
"FirstName": "First",
"LastName": "Last"
}
}
]
}
pom.xml
)<properties>
<restassured.version>5.1.1</restassured.version>
</properties>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.8.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<version>${restassured.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>json-schema-validator</artifactId>
<version>${restassured.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.github.tomakehurst</groupId>
<artifactId>wiremock-jre8</artifactId>
<version>2.33.2</version>
<scope>test</scope>
</dependency>
</dependencies>
src/test/resources/schema.json
){
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"Data": {
"type": "array",
"items": [
{
"type": "object",
"properties": {
"Id": {
"type": "integer"
},
"Name": {
"type": "string"
}
},
"required": [
"Id",
"Name"
]
}
]
}
},
"required": [
"Data"
]
}
src/test/resources/__files/data.json
){
"Data": [
{
"Id": 1,
"Name": "ABC"
}
]
}
src/test/resources/__files/data-invalid.json
){
"Data": [
{
"Id": 1,
"Name": {
"FirstName": "First",
"LastName": "Last"
}
}
]
}
src/test/java/info/brunov/stackoverflow/question72903880/DataServiceTest.java
)package info.brunov.stackoverflow.question72903880;
import com.github.tomakehurst.wiremock.WireMockServer;
import com.github.tomakehurst.wiremock.client.WireMock;
import com.github.tomakehurst.wiremock.core.WireMockConfiguration;
import io.restassured.RestAssured;
import io.restassured.builder.RequestSpecBuilder;
import io.restassured.filter.log.LogDetail;
import io.restassured.module.jsv.JsonSchemaValidator;
import io.restassured.specification.RequestSpecification;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
public final class DataServiceTest {
private final WireMockServer server;
private final RequestSpecification requestSpecification;
public DataServiceTest() {
server = new WireMockServer(
WireMockConfiguration.wireMockConfig().dynamicPort()
);
server.stubFor(
WireMock.get("/data")
.willReturn(
WireMock.aResponse().withBodyFile("data.json")
)
);
server.stubFor(
WireMock.get("/data-invalid")
.willReturn(
WireMock.aResponse().withBodyFile("data-invalid.json")
)
);
server.start();
final RequestSpecBuilder requestSpecBuilder = new RequestSpecBuilder();
requestSpecBuilder.setPort(server.port());
requestSpecification = requestSpecBuilder.build();
}
@AfterEach
void tearDown() {
server.stop();
}
@Test
public void getData_responseConformsSchema_success() {
RestAssured.given()
.spec(requestSpecification)
.get("/data")
.then()
.log().ifValidationFails(LogDetail.ALL)
.assertThat()
.statusCode(200)
.body(JsonSchemaValidator.matchesJsonSchemaInClasspath("schema.json"));
}
// NOTE: Deliberately failing test.
@Test
public void getInvalidData_responseConformSchema_fail() {
RestAssured.given()
.spec(requestSpecification)
.get("/data-invalid")
.then()
.log().ifValidationFails(LogDetail.ALL)
.assertThat()
.statusCode(200)
.body(JsonSchemaValidator.matchesJsonSchemaInClasspath("schema.json"));
}
}