Javascript to groovy objects in GEB functional test cases
Use Case
While writing functional tests sometimes we need to test whether a certain javascript objects have some particular values.
If we have a JavaScript object such as in our page
[code]
var myObj = { attr1 : ‘attr1-val’, attr2 : ‘attr2-val’};
[/code]
then after reaching that page we can execute the below in our GEB spec file to get that Object as a Map.
[code]
js.exec("return myObj")
[/code]
Taking this object we can compare the values from some other places for validation e.g. compare with an API to make sure that the data present here matches the data being received from the server.
But sometimes our objects may be bigger or complex. In such situation it could be better to have these objects as Groovy objects so we can easily compare them.
Solution
So we can have a class like
[code]
@EqualsAndHashCode
class MyArgs {
String attr1
String attr2
}
[/code]
Now we can get an object in our GEB tests by using
[code]
MyArgs myArgs = js.exec("return myObj") as MyArgs
[/code]
Problem – Extra properties in JS Object
But what would happen in case the JavaScript object had an extra key?
[code]
var myObj = { attr1 : ‘attr1-val’, attr2 : ‘attr2-val’, ‘EXTRA’: ‘EXTRA-VAL’};
[/code]
Our above code will break as there will be no property such as EXTRA in our MyArgs class.
We will see something like
[code]
groovy.lang.MissingPropertyException: No such property: EXTRA for class: MyArgs
[/code]
Solution
We can take care of any extra properties by using a little metaprogramming trick
[code]
@EqualsAndHashCode
class MyArgs {
String attr1
String attr2
def propertyMissing(String name, value){
// WARNING DON’T remove this
}
}
[/code]
Now only the relevant properties will be mapped and no exception will be thrown in case extra properties are present.