Grails’ JSONObject.NULL More or Less Equal To Null
Since Groovy 1.8 we can check if a Map is equal to another Map if the keys and values are the same. Very convenient in tests for example.
def someMap = [age: 34, name: "Ted"] assert someMap == [name: "Ted", age: 34]
Today I kept staring at a failure, while testing some x and y graph data points returned by a Grails controller, where two Maps were somehow not equal according to Spock, while even the assertion’s output looked ‘equal’.
when: controller.milkYield() then: response.json and: "series are present" def series = response.json series.size() == 2 and: "realized series is correct" ... and: "predicted series is correct" def predictedSeries = series predictedSeries.values.size() == 2 predictedSeries.values == [y:null, x:'Mar'] predictedSeries.values == [y:121, x:'Apr']
Condition not satisfied: predictedSeries.values == [y:null, x:'Mar'] | | | | | | | false | | [y:null, x:Mar] | [[y:null, x:Mar], [y:121, x:Apr]] [values:[[y:null, x:Mar], [y:121, x:Apr]]]
[y:null, x:Mar] equal to
After having checked explicitly with
predictedSeries.values.x == 'Mar' predictedSeries.values.y == null // <- better be null!
I remembered again I was dealing with JSON data in Grails, which uses the Null Object pattern. Keeps biting me every now and then :-)
Condition not satisfied: predictedSeries.values.y == null | | | | | | | | | false | | | null (org.codehaus.groovy.grails.web.json.JSONObject$Null) | | [y:null, x:Mar] | [[y:null, x:Mar], [y:121, x:Apr]] [values:[[y:null, x:Mar], [y:121, x:Apr]]]
There are some long time posts already describing this behaviour that
JSONObject.NULL was not equal to
JSONObject.NULL.equals(null) // true JSONObject.NULL == null // false!!
and some meta-class changes you could do were suggested at the time. Seems reported GRAILS-7739 (Wrong == and asBoolean behavior for JSONObject.Null) says it’s been fixed a few years back in Grails 2.2.
Atleast something has been fixed. Although you still can not do
JSONObject.NULL == null, you can change the assertion to using Groovy Truth since
!JSONObject.NULL does work.
!predictedSeries.values.y // or predictedSeries.values == [y: JSONObject.NULL, x:'Mar'] if you like
And of course I should remember null in (console) output is always a String representation leading to “null” – such as
|Reference:||Grails’ JSONObject.NULL More or Less Equal To Null from our JCG partner Ted Vinke at the Ted Vinke’s Blog blog.|