englishteeth.co.uk

… the weblog of Ian “English Teeth” Robinson
  • rss
  • Home

Groovy on Grails and my “Test First” impasse

September 4, 2008 | 9:08 am

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!

Comments
No Comments »
Categories
development
Tags
grails, groovy, hibernate, mock, testing
Comments rss Comments rss
Trackback Trackback

Grails Unit Testing: How to mock a closure

August 29, 2008 | 1:07 pm

I have found numerous resources on testing in grails, unit testing and Using MockFor and StubFor in groovy. However, given that closures are one of the key features of groovy, I found very little on how to accommodate them in testing.

The following is a simple controller with a list action that returns a set of Customer domain objects from a database and this action applies some simple filter criteria (thanks to this post I came across):

   def list = {
        def items

        if(!params.max) params.max = 10
        if(!params.sort) params.sort = "lastUpdated"
        if(!params.order) params.order= "desc"
        if (params?.filter) {
            def criteria = Customer.createCriteria()
            items = criteria.list(params) {
                or {
                        ilike ('surname', "%${params.filter}%")
                        ilike ('forename', "%${params.filter}%")
                        ilike ('emailAddress', "%${params.filter}%")
                }
            }
        }
        else {
            items = Customer.list (params)
        }

        render (view: 'list', model: [ customerList: items, filter:params.filter ], params: params)
    }

This action uses the Hibernate Criteria Builder to construct the query.

When unit testing Grails does not inject any of the dynamic methods and so these must be provided for. For this I covered the dynamic controller methods in the set up and tear down operations (thanks wholly to Glen Smith’s MockFor(March): Unit Testing Grails Controllers…

    def redirectParams
    def renderParams
    def params

    /** Setup metaclass fixtures for mocking. */
    void setUp() {

        params = [ : ]
        CustomerController.metaClass.getParams = { -> params }

        redirectParams = [ : ]
        CustomerController.metaClass.redirect = { Map args -> redirectParams = args  }

        renderParams= [ : ]
        CustomerController.metaClass.render = { Map args -> renderParams = args  }

    } 

    /** Remove metaclass fixtures for mocking. */
    void tearDown() {
        def remove = GroovySystem.metaClassRegistry.&removeMetaClass
        remove CustomerController
    }

The dynamic methods for the domain class I covered in the test where they were used.

    void testNoFilterReturnsList() {

        def testItems = [ 'x', 'y', 'z' ]

        params['filter'] = null ;

        // mock the static list and count methods
        Customer.metaClass.static.list = { Map params -> testItems } 

        CustomerController cc = new CustomerController()
        cc.list()

        assertNull renderParams.model.filter
        assertEquals testItems, renderParams.model.customerList

    }

This could hardly be simpler and is covered in much more detail elsewhere. Where I ran into difficulty was testing the the criteria was applied.

I wanted to provide a mock object for the org.hibernate.Criteria object returned for the domain.
def customerCriteria = new MockFor(org.hibernate.Criteria)
Defining expectations on the mock object is straight forward too, just demand it!
customerCriteria.demand.list { -> testItems }
Except that what ever I seemed to try would not match the signature of the call to list that I was trying to do in the filter test above.

Despite being a little elusive, the answer was simple enough. The closure defining the search criteria is a parameter to the call. There must be a list method declared with a signature along the lines of
def list (Map params, Closure criteria)(At least, that’s what I had to do in a test class to mimic that results I was seeing.)

So, to define a demand to match that… well, just treat it as such.

    void testFilterAppliedToCriteria() {

        def testItems = [ 'x', 'y', 'z' ]

        params['filter'] = 'search on something' ;

        def customerCriteria = new MockFor(org.hibernate.Criteria)
        customerCriteria.demand.list { Map params, Closure cls -> testItems }
        Customer.metaClass.static.createCriteria = { org.hibernate.Criteria }
        customerCriteria.use{
        	CustomerController cc = new CustomerController()
        	cc.list()

        	assertEquals params.filter, renderParams.model.filter
        	assertEquals testItems, renderParams.model.customerList
        }
    }

I continue to stumble through, though I’m becoming more convinced that I don’t know what I am doing.

Comments
3 Comments »
Categories
development
Tags
closures, grails, groovy, hibernate, testing
Comments rss Comments rss
Trackback Trackback

Grails on an existing database

May 19, 2008 | 4:20 pm

The usual grails approach is to create the database to reflect the model, but if there is an existing database there are a few things to bear in mind.

I got a good start on this from Grails on Oracle, but it’s a bit out of date now and is still from a having control over the database angle.

In the configuration
I was getting an “Unsupported feature” org.springframework.jdbc.support.MetaDataAccessException
Although this appeared to be down to the target database not supporting auto-detection, I was providing org.hibernate.dialect.OracleDialect in the hibernate properties. However, after checking the documentation on Grails Data Sources, this should have been in the data source.

dataSource {
  pooled = true
  driverClassName = "oracle.jdbc.OracleDriver"
  dialect = "org.hibernate.dialect.OracleDialect"
  username = "username"
  password = "password"
}
hibernate {
  show_sql = "true"
  cache.provider_class = "org.hibernate.cache.NoCacheProvider"
  current_session_context_class = "thread"
}

environments {
  development {
    dataSource {
      dbCreate = "update"
      url = "jdbc:oracle:thin:@path:port:sid"
    }
  }
}

After sorting that, the errors were SQL grammar related and needed to be dealt with at the domain object level; show_sql = “true” did work in the hibernate properties and helped identify where these were coming from.

In the domain objects
The differences are captured in mapping declaration… (duh!)

  • I didn’t want my domain object to be the same name as the table.
  • The id column in the table was not to the grails convention.
  • There was no version column in the table.

(There was a lastUpdated column, but the first task was to get something working before I worried about optimistic locking!)

class MyDomainObject {

  static mapping = {
    table 'db_domain_object'
    id column:'domain_object_id'
    version false // no version column in table
  }

  String someProperty
  String someOtherProperty

}

Nothing earth shattering or difficult, but not exactly obvious from the server output.

Comments
2 Comments »
Categories
development
Tags
db, grails, groovy, hibernate, oracle, sql
Comments rss Comments rss
Trackback Trackback

This week I have mostly been reading…

May 4, 2008 | 11:59 pm

I was needing to brush up a style sheet and wanted a clean way to apply drop shadows, which I found here.

I often use the in-line lists for page navigation, but I hadn’t come across the use of floats described in this post here and here. However, while looking for a slick way of producing “rounded corners”, I found an implementation using sliding doors that happened to have the drop shadow I was after as part of the border image here, though I must admit to preferring the variation I found here.

And when I needed to print CSS background images, this post proved most helpful.

Along the way, I stumbled across the site Position Is Everything which looked like it might be worth making a note of.

Following the news of the Spring Source Application Platform I need to look back at this post on web applications and OSGi.

I also enjoyed this post on converting Java to Groovy.

Following a little foray down the path of UML modelling XML Schemas for a colleague, this article articulated what I was trying to get across much better than I could have. Rational Software Architect unfortunately couldn’t quite grasp it quite as easily. No change there then…

Comments
No Comments »
Categories
development
Tags
css, groovy, java, links, osgi, spring, uml, xml
Comments rss Comments rss
Trackback Trackback

This week I have mostly been reading…

April 20, 2008 | 11:59 pm

Some of my poking around in groovy on grails led me to a tutorial here.

This seemed well written and worked well and I explored a little more of his site and along the way I picked up a reference to a text on grails here.

Which itself enticed me along to the authors site here.

Where I found a link to an interesting take on the closures in Java debate here.

and an application that, if it works, might just negate the need that resulted me in dusting off my weblog here.

Useful, or at least vaguely interesting stuff on browser usage and trends here.

How to make a Sawed-off USB Key here.

Oh and that voice mail to text thing on last week’s gadget show that I must check out further here.

Comments
No Comments »
Categories
development, miscellaneous
Tags
grails, groovy, java, links
Comments rss Comments rss
Trackback Trackback

« Previous Entries

Author

Ian Robinson is a relatively agile software engineer interested in things both sides of the object relational divide and beyond.

Categories

  • development (35)
  • miscellaneous (20)
  • music (7)
  • software (13)

Blogroll

  • Dan North
  • Dave Astels
  • Dave Wood
  • eirikso.com
  • Matt Raible
  • Object Mentor Blog
  • The Ancient Art of Programming
  • The Wisdom of Ganesh

Tags

active-mq architecture bauhaus blu-ray css db eclipse esb festivals freesat gorm grails groovy hd hd-dvd hibernate java jboss jms junit links mce media center mini music oracle osgi patterns pirsig plugins satellite soa software spring sql struts2 testing themes tools tv web wordpress xml xpath xslt
rss Comments rss valid xhtml 1.1 design by jide powered by Wordpress get firefox