JSON Assert lib released
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.
So having such a Groovy DSL:
Resulted in creation of the following server side response verification
AccuREST users stated that their biggest problem is this part:
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:
If your using Gradle just add (check the latest version number):
and if Maven just add:
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.
Best examples are tests. I'll show you a couple of them here.
Example 1
Having a JSON:
It would be nice to:
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('abc@abc.com')),
callback_url: $(stub(regex(hostname())), test('https://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('not.existing@user.com'))}]"
)
}
}
Resulted in creation of the following server side response verification
given:
def request = given()
.header('Content-Type', 'application/json')
.body('{"email":"abc@abc.com","callback_url":"https://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.)