Test json w/ json path

While building RESTFul services you may want to write an integration test to validate the json response. One way to do this is by using JSONPath, similar to XPATH, which has the ability to extract parts of a given document. In the snippets below we will combine JSONPath, junit and hamcrest to look for a field, validate the size of a json array and check if an elements starts with a specific string.

Json field test

/**
 * Test fields
 */
@Test
public void test_json_fields () {

    String rawJson = "{\r\n   \"id\":1,\r\n   \"description\":\"Biodiesel XOXO pug, irony roof party Helvetica selfies vinyl...\",\r\n   \"url\":\"http://hipsteripsum.me/\"\r\n}";

    String description = JsonPath.read(rawJson, "$.description");
    String url = JsonPath.read(rawJson, "$.url");

    logger.info(description);

    assertEquals("Biodiesel XOXO pug, irony roof party Helvetica selfies vinyl...", description);
    assertThat(url, containsString("http://"));
}

Validate json array size

/**
 * Validate size of json array
 */
@Test
public void test_json_array_size () {

    String rawJson = "{\r\n   \"labels\":[\r\n      {\r\n         \"url\":\"https://api.github.com/...\",\r\n         \"name\":\"enhancement\",\r\n         \"color\":\"84b6eb\"\r\n      },\r\n      {\r\n         \"url\":\"https://api.github.com/...\",\r\n         \"name\":\"bug\",\r\n         \"color\":\"84b6eb\"\r\n      },\r\n      {\r\n         \"url\":\"https://api.github.com/...\",\r\n         \"name\":\"Technical\",\r\n         \"color\":\"84b6eb\"\r\n      },\r\n      {\r\n         \"url\":\"https://api.github.com/...\",\r\n         \"name\":\"User Story\",\r\n         \"color\":\"84b6eb\"\r\n      }\r\n   ]\r\n}";

    List<Object> labels = JsonPath.read(rawJson, "$.labels");

    logger.info(labels);

    assertThat(labels, hasSize(4));
}

Output

[
{"color":"84b6eb","name":"enhancement","url":"https:\/\/api.github.com\/..."},
{"color":"84b6eb","name":"bug","url":"https:\/\/api.github.com\/..."},
{"color":"84b6eb","name":"Technical","url":"https:\/\/api.github.com\/..."},
{"color":"84b6eb","name":"User Story","url":"https:\/\/api.github.com\/..."}
]

Array elements start with

/**
 * Test each url in array starts with http OR https
 */
@Test
public void test_json_array_elements_start_with () {

    String rawJson = "{\r\n   \"labels\":[\r\n      {\r\n         \"url\":\"https://api.github.com/...\",\r\n         \"name\":\"enhancement\",\r\n         \"color\":\"84b6eb\"\r\n      },\r\n      {\r\n         \"url\":\"http://api.github.com/...\",\r\n         \"name\":\"bug\",\r\n         \"color\":\"84b6eb\"\r\n      },\r\n      {\r\n         \"url\":\"https://api.github.com/...\",\r\n         \"name\":\"Technical\",\r\n         \"color\":\"84b6eb\"\r\n      },\r\n      {\r\n         \"url\":\"http://api.github.com/...\",\r\n         \"name\":\"User Story\",\r\n         \"color\":\"84b6eb\"\r\n      }\r\n   ]\r\n}";

    List<Object> urls = JsonPath.read(rawJson, "$.labels[*].url");

    logger.info(urls);

    assertThat(urls, hasItem(
            anyOf(startsWith("https://"),
                    startsWith("http://"))));
}

Output

[
"https:\/\/api.github.com\/...",
"http:\/\/api.github.com\/...",
"https:\/\/api.github.com\/...",
"http:\/\/api.github.com\/..."
]