Groovy on Grails and my “Test First” impasse
I’ve hit what would be a test first impasse (if I had tried to write my test first). So in an attempt to leave it alone, I’ll record where I got to and the resources that I think nearly got me to a solution…
I have a domain object for which I want to return a filtered set. I know that this can be done as a closure to the list method of hibernate criteria and having figured out how to mock a closure I can assert that a filter has indeed been applied.
def criteria = Customer.createCriteria()
items = criteria.list(params) {
or {
ilike ('surname', "%${params.filter}%")
ilike ('forename', "%${params.filter}%")
ilike ('emailAddress', "%${params.filter}%")
}
}
---
def customerCriteria = new MockFor(org.hibernate.Criteria)
customerCriteria.demand.list {
Map params,
Closure cls -> testItems
}
Customer.metaClass.static.createCriteria = { org.hibernate.Criteria }
But how can I assert that the filter closure contains/does what I want?
Having mocked the closure call, I now want to define what it is supposed to do in my unit test.
I just can’t figure out how and I have started delving much deeper into how closures work than I originally wanted to. Unfortunately, I don’t seem to get any further than the MetaClass, where everything is still a little abstract. There must be some representation of the code to be run/resolved in there somewhere!?
I’ve poured over the hierarchy for package groovy.lang and pages on Closures and the ExpandoMetaClass - GroovyObject Methods.
Kick started by Fun with Groovy and the Reflection API and definitely helped by What methods does my Groovy/Grails class have? I distilled my problem to a script and proceeded to dump anything and everything I could think of or come across…
class MyClassUnderTest {
def foo() { return "foo" }
def bar() { return "bar" }
def ray() { return "ray" }
def someMethod(Closure val) {
println("Closure:")
println(val.dump())
println("-----------------------------------------------------------------")
println("My Closure: ")
println(val.getMyClosure().dump())
println("-----------------------------------------------------------------")
println("Meta Class: ")
println(val.getMyClosure().metaClass.dump())
println("-----------------------------------------------------------------")
println("My Meta Class: ")
println(val.getMyClosure().metaClass.myMetaClass.dump())
println("-----------------------------------------------------------------")
println("My Meta Class Methods Index: ")
println(val.getMyClosure().metaClass.myMetaClass.metaMethodIndex.table*.name.sort().unique() )
println("-----------------------------------------------------------------")
println(val.getMyClosure().metaClass.inheritedMetaMethods*.name.sort().unique())
println(val.getMyClosure().metaClass.methods*.name.sort().unique())
println("-----------------------------------------------------------------")
println(val.getMyClosure().metaClass.theClass.dump())
println("-----------------------------------------------------------------")
println("Constructors:") val.getMyClosure().metaClass.theClass.declaredConstructors.each {
println it.toGenericString()
}
println("-----------------------------------------------------------------")
println("Methods:") val.getMyClosure().metaClass.theClass.declaredMethods.each {
println it.toGenericString()
}
println("-----------------------------------------------------------------")
return 'result!'
}
}
def cut = new MyClassUnderTest()
def myClosure = {
foo ('valueOne')
bar ('valueTwo')
ray ('valueThree')
'valueFour'
}
cut.someMethod { myClosure }
I thought I might have struck lucky when came across a post by Danno Ferrin who had learned more than he wanted to know about groovy.lang.Closure. This cleared up a great deal about scope and lead me to a post by Guillaume Laforge on knowing which variables are bound or not in a Groovy script.
Unfortunately the actual contents of the closure still allude me, but I’ve got work to do and this has had far more of my time than I can justify!