I'm really happy to present the Json Assert library - over-the-weekend project that came out from the AccuREST library. This post will describe the rationale behind creating this tool and how to use it.
Rationale
In AccuREST (the Consumer Driven Contracts implementation library) we're creating tests of the server side. For more information on what is AccuREST and what Consumer Driven Contracts is check the AccurREST wiki. Anyways, we're checking if the response from the server matches the one described in the contract.So having such a Groovy DSL:
io.codearte.accurest.dsl.GroovyDsl.make {
priority 1
request {
method 'POST'
url '/users/password'
headers {
header 'Content-Type': 'application/json'
}
body(
email: $(stub(optional(regex(email()))), test('[email protected]')),
callback_url: $(stub(regex(hostname())), test('http://partners.com'))
)
}
response {
status 404
headers {
header 'Content-Type': 'application/json'
}
body(
code: value(stub("123123"), test(optional("123123"))),
message: "User not found by email = [${value(test(regex(email())), stub('[email protected]'))}]"
)
}
}
Resulted in creation of the following server side response verification
given:
def request = given()
.header('Content-Type', 'application/json')
.body('{"email":"[email protected]","callback_url":"http://partners.com"}')
when:
def response = given().spec(request)
.post("/users/password")
then:
response.statusCode == 404
response.header('Content-Type') == 'application/json'
and:
DocumentContext parsedJson = JsonPath.parse(response.body.asString())
!parsedJson.read('''$[?(@.code =~ /(123123)?/)]''', JSONArray).empty
!parsedJson.read('''$[?(@.message =~ /User not found by email = \\[[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}\\]/)]''', JSONArray).empty
AccuREST users stated that their biggest problem is this part:
!parsedJson.read('''$[?(@.code =~ /(123123)?/)]''', JSONArray).empty
!parsedJson.read('''$[?(@.message =~ /User not found by email = \\[[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}\\]/)]''', JSONArray).empty
They said that JSON Paths are too difficult for them to read.
That's why I've created the JSON Assert library. So that instead of the aforementioned code one gets sth like this:
assertThatJson(parsedJson).field('code').matches('123123?')
assertThatJson(parsedJson).field('message').matches('User not found by email = \\[[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}\\]/)]');
How to add it to your project
If your using Gradle just add (check the latest version number):
testCompile `com.blogspot.toomuchcoding:jsonassert:0.1.2`
and if Maven just add:
<dependency>
<groupId>com.blogspot.toomuchcoding</groupId>
<artifactId>jsonassert</artifactId>
<version>0.1.2</version>
</dependency>
How to use it
Since almost everything in JSON Assert is package scoped you have access to two public classes. One of which is the JsonAssertion class. It gives you a couple of public methods that give you the entry point to the fluent interface of the library.
You can check the JavaDocs of the JsonVerifiable interface in order to see what kind of methods can be used.
Examples
Best examples are tests. I'll show you a couple of them here.
Example 1
Having a JSON:
[ {
"some" : {
"nested" : {
"json" : "with value",
"anothervalue": 4,
"withlist" : [
{ "name" :"name1"} , {"name": "name2"}, {"anothernested": { "name": "name3"} }
]
}
}
},
{
"someother" : {
"nested" : {
"json" : "with value",
"anothervalue": 4,
"withlist" : [
{ "name" :"name1"} , {"name": "name2"}
]
}
}
}
]
Instead of writing:
$[*].some.nested.withlist[*].anothernested[?(@.name == 'name3')]
you can write
Example 2
Having a JSON:
assertThat(json).array().field("some").field("nested").array("withlist").field("anothernested").field("name").isEqualTo("name3")
Example 2
Having a JSON:
{
"property1": [
{ "property2": "test1"},
{ "property3": "test2"}
]
}
Instead of writing:
$.property1[*][?(@.property2 == 'test1')]
you can write
assertThat(json).array("property1").contains("property2").isEqualTo("test1")
Future plans
It would be nice to:
- integrate with AssertJ
- add more JSON Path features (functions, filters etc.)
Links
- JSON Assert
- AccuREST
- Video about AccuREST by Olga Maciaszek-Sharma
- Jayway JSON Path
- AssertJ