-
Notifications
You must be signed in to change notification settings - Fork 10
Checking JSON
The testing library provides a powerful tool to test JSON objects based on static expect
method described in the Presentation error section. To test JSON, you need to write expect(string).asJson().check(template)
. After checking you are guaranteed to have correct JSON because otherwise testing library will throw Wrong answer
automatically.
All the static methods you need are located in org.hyperskill.hstest.testing.expect.json.JsonChecker
class. It is recommended to statically import all you need from there. If you want to use regular expression patterns to check string values, you may want to statically import method compile
as well.
import static java.util.regex.Pattern.compile;
import static org.hyperskill.hstest.testing.expect.json.JsonChecker.*;
You can create templates with the following methods:
-
any()
matches any object, array, number, or null. -
isObject(...)
matches JSON object -
isArray(...)
matches JSON array -
isString(...)
matches JSON string -
isNumber(...)
matches JSON number -
isInteger(...)
matches JSON number that can be represented as an integer -
isDouble(...)
matches JSON number that can be represented as a double -
isBoolean(...)
matches JSON bool -
isNull()
matches JSON null
All the methods return objects that inherit JsonBaseBuilder
so you can use them to check objects' values and arrays' items.
isObject(...)
returns JsonObjectBuilder
and can be configured using .value(...)
methods described below.
Available methods to create object template:
-
isObject()
without configuration matches an empty object -
isObject(JsonAnyBuilder unused)
is only used to writeisObject(any())
which matches an object with any key-value pairs. Cannot be configured.
Available methods to configure object template:
-
.value(String key, int value)
matches object that contains keykey
with valuevalue
-
.value(String key, double value)
same as 1 -
.value(String key, boolean value)
same as 1 -
.value(String key, String value)
same as 1 -
.value(String key, Pattern valueRegex)
matches object that contains keykey
with string value that matches patternvalueRegex
-
.value(String key, int... values)
matches object that contains keykey
with value as an array ofvalues
-
.value(String key, double... value)
same as 6 -
.value(String key, boolean... value)
same as 6 -
.value(String key, String... value)
same as 6 -
.value(Pattern keyRegex, int value)
matches object that contains key that matches patternkeyRegex
with valuevalue
-
.value(Pattern keyRegex, double value)
same as 10 -
.value(Pattern keyRegex, boolean value)
same as 10 -
.value(Pattern keyRegex, String value)
same as 10 -
.value(Pattern keyRegex, Pattern valueRegex)
matches object that contains key that matches patternkeyRegex
with string value that matches patternvalueRegex
-
.value(Pattern keyRegex, int... values)
matches object that contains key that matches patternkeyRegex
with value as an array ofvalues
-
.value(Pattern keyRegex, double... value)
same as 15 -
.value(Pattern keyRegex, boolean... value)
same as 15 -
.value(Pattern keyRegex, String... value)
same as 15 -
.value(StringChecker key, int value)
matches object that contains key that matches checkerkey
with valuevalue
-
.value(StringChecker key, double value)
same as 19 -
.value(StringChecker key, boolean value)
same as 19 -
.value(StringChecker key, String value)
same as 19 -
.value(StringChecker key, Pattern valueRegex)
matches object that contains key that matches checkerkey
with value that matches patternvalueRegex
-
.value(StringChecker key, int... values)
matches object that contains key that matches checkerkey
with value as an array ofvalues
-
.value(StringChecker key, double... values)
same as 24 -
.value(StringChecker key, boolean... values)
same as 24 -
.value(StringChecker key, String... values)
same as 24 -
.value(String key, JsonBaseBuilder value)
matches object that contains keykey
with value that matches templatevalue
-
.value(Pattern regex, JsonBaseBuilder value)
matches object that contains key that matches patternkeyRegex
with value that matches templatevalue
-
.value(StringChecker key, JsonBaseBuilder value)
matches object that contains key that matches checkerkey
with value that matches templatevalue
StringChecker
is a functional interface that takes a String
key and returns a boolean. If it returns true, the match is considered successful. For example, checker key -> key.length() < 10
would match a key that has a length fewer than 10 characters.
To test the following JSON object:
{
"date": "2019-10-11",
"time": "20:11",
"cost": 12.32,
"pic": "qwe.png",
"all_years": [2011, 2013, 2014, 2020]
}
You can use the following template:
isObject()
.value("date", compile("\\d{4}-\\d{2}-\\d{2}"))
.value("time", compile("\\d{2}:\\d{2}"))
.value("cost", isNumber())
.value(compile("pic|img"), isString(s -> s.endsWith(".png"))
.value(key -> key.endsWith("years"), 2011, 2013, 2014, 2020)
isArray(...)
returns JsonArrayBuilder
and can be configured using .item(...)
methods described below.
Available methods to create array template:
-
isArray()
without configuration matches an empty array -
isArray(int length)
matches an array oflength
elements -
isArray(JsonBaseBuilder itemsTemplate)
matches an array whose elements matchitemsTemplate
. Example:isArray(isInteger())
matches an array of any integers,isArray(any())
matches any array. -
isArray(int length, JsonBaseBuilder itemsTemplate)
matches an array oflength
elements and all of them should matchitemsTemplate
-
isArray(int... values)
matches an array ofvalues
-
isArray(double... values)
same as 5 -
isArray(boolean... values)
same as 5 -
isArray(String... values)
same as 5 -
isArray(ArrayLengthChecker lengthChecker)
matches an array whose length matcheslengthChecker
-
isArray(ArrayLengthChecker lengthChecker, JsonBaseBuilder itemsTemplate)
matches an array whose length matcheslengthChecker
and items matchitemsTemplate
template
ArrayLengthChecker
is a functional interface that takes an integer key and returns a boolean. If it returns true, the match is considered successful. For example, checker len -> len < 10
would match an array with less than 10 elements.
Available methods to configure array template:
-
.item(int value)
matches array whose next element is equal tovalue
-
.item(double value)
same as 1 -
.item(boolean value)
same as 1 -
.item(String value)
same as 1 -
.item(Pattern regex)
matches array whose next element is a string that matches patternregex
. -
.item(JsonBaseBuilder value)
matches array whose next element matches templatevalue
. Example:.item(isInteger())
matches any integer item,.item(any())
matches any item. -
.anyOtherItems()
in case you allow any other values in a JSON object besides those that you have already configured. After calling this method you can't configure other values so this method should be last to call.
To test the following JSON array:
[
{
"num": 12,
"why": "flew high"
},
{
"number": 23,
"reason": "flew fast"
},
45,
null,
false
]
You can use the following template:
isArray()
.item(isObject()
.value("num", isInteger(i -> i == 12 || i == 13))
.value(compile("..y"), "flew high"))
.item(isObject()
.value("number", 23)
.value("reason", "flew fast"))
.item(45)
.item(isNull())
.anyOtherItems())
isString(...)
returns `JsonStringBuilder.
Available methods to create string template:
-
isString()
matches any string -
isString(String value)
matches string that is equal tovalue
-
isString(Pattern regex)
matches string that matches patternregex
-
isString(StringChecker checker)
matched string that matcheschecker
StringChecker
is a functional interface that takes a String
and returns a boolean. If it returns true, the match is considered successful. For example, checker str -> str.length() < 10
would match a string whose length is less than 10.
isNumber(...)
returns JsonNumberBuilder
or JsonIntegerBuilder
or JsonDoubleBuilder
based on arguments passed to it.
isInteger(...)
returns JsonIntegerBuilder
isDouble(...)
returns JsonDoubleBuilder
Available methods to create number template:
-
isNumber()
matches any number, integer or double -
isNumber(int value)
matches integervalue
-
isNumber(double value)
matches doublevalue
-
isInteger()
matches any integer -
isInteger(int value)
same as 2 -
isInteger(IntegerChecker checker)
matches integer that matcheschecker
-
isDouble()
matches any double -
isDouble(double value)
same as 3 -
isDouble(DoubleChecker checker)
matches double that matcheschecker
IntegerChecker
is a functional interface that takes an integer and returns a boolean. If it returns true, the match is considered successful. For example, checker num -> num < 10
would match an integer that is less than 10.
DoubleChecker
is a functional interface that takes a double and returns a boolean. If it returns true, the match is considered successful. For example, checker num -> num < 0.5
would match a double that is less than 0.5.
isBoolean(...)
returns JsonBooleanBuilder
.
Available methods to create boolean template:
-
isBoolean()
matches any boolean -
isBoolean(boolean value)
matches booleanvalue
-
isBoolean(BooleanChecker checker)
matches boolean that matcheschecker
BooleanChecker
is a functional interface that takes a boolean and returns a boolean. If it returns true, the match is considered successful. For example bool -> bool == computeOtherBool()
.
For a given JSON:
{
"name": "123",
"car": {
"model": "Tesla Roadster",
"year": 2018,
"repairs": [
{
"date": "2019-10-11",
"time": "20:11",
"cost": 12.32,
"pic": "qwe.png",
"all_years": [2011, 2013, 2014, 2020]
},
{
"date": "2019-11-12",
"time": "21:12",
"cost": 34,
"img": "wer.png",
"all_years": [2011, 2013, 2014, 2020]
}
]
},
"rocket": {
"name": "Falcon 9",
"launches": "89+",
"mentioned": [
12, 34, 56
],
"memorable": [
{
"num": 12,
"why": "flew high"
},
{
"number": 23,
"reason": "flew fast"
},
45,
null,
false
]
},
"options": {
"12": null
}
}
You can check it with the following template:
isObject()
.value("name", isString())
.value("car", isObject()
.value("model", "Tesla Roadster")
.value("year", 2018)
.value("repairs", isArray(2,
isObject()
.value("date", compile("\\d{4}-\\d{2}-\\d{2}"))
.value("time", compile("\\d{2}:\\d{2}"))
.value("cost", isNumber())
.value(compile("pic|img"), isString(s -> s.endsWith(".png")))
.value(key -> key.endsWith("years"), 2011, 2013, 2014, 2020))))
.value("rocket", isObject()
.value("name", "Falcon 9")
.value("launches", compile("[0-9]+\\+"))
.value("mentioned", isArray(12, 34, 56))
.value("memorable", isArray()
.item(isObject()
.value("num", isInteger(i -> i == 12 || i == 13))
.value(compile("..y"), "flew high"))
.item(isObject()
.value("number", 23)
.value("reason", "flew fast"))
.item(45)
.item(isNull())
.anyOtherItems()))
.value("options", any())
- Home
- About
- Initial setup
- Writing tests
- Guidelines for writing tests
- Outcomes of testing
- Generating and checking
- Presentation error
- Checking JSON
- Testing solutions written in different languages
- Creating Hyperskill problems based on hs-test
- Testing Java Swing applications
- Testing Java Spring applications
- Testing Ktor applications