englishteeth.co.uk

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

Groovy on Grails and my “Test First” impasse

Ian | September 4, 2008

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

Ian | August 29, 2008

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
4 Comments »
Categories
development
Tags
closures, grails, groovy, hibernate, testing
Comments rss Comments rss
Trackback Trackback

Grails ClassCastException for Application

Ian | August 21, 2008

Having persevered with mapping my existing database in grails, it actually made for much cleaner domain objects.

I never much liked when hibernate started creeping out of configuration and into the code via Java annotations, so on the same score, it was cathartic to remove the database aware gorm mappings from my domain classes.

Adding the hibernate configuration was straight forward and clean and tucked away in the conf/hibernate directory; an hibernate.cfg.xml file listing the mapping resources and an hbm.xml resource file for each entity.

All was going swimmingly until I was adding my last domain class; modelling an Application.

As soon as I wanted to “show” a particular Application I was getting a ClassCastException.

It would appear that I’m not the first to hit this, so luckily I didn’t have waste too much time trying to figure out why:

application/create throws java.lang.ClassCastException: Application cannot be cast to javax.servlet.ServletContext

Apparently…

there is a variable in the GSP binding called ‘application’ that is the ServletContext this gets overridden when you return the model from the controller

The bug is on create, but I guess as I am coming from the legacy database angle, I didn’t have to “create” before I tried to “show”.

Mmm.

Comments
No Comments »
Categories
development
Tags
domain, gorm, grails, hibernate, java
Comments rss Comments rss
Trackback Trackback

Grails on an existing database revisited

Ian | August 20, 2008

Some time ago I looked at what was necessary to have Grails work on an existing database rather than the green field scenario painted in most examples.

It seemed straight forward enough, but beyond curiosity, I didn’t have anything I was particularly trying to achieve, so I moved along.

Yesterday, once again messing around with grails, I found something I couldn’t seem to achieve via gorm.

Basically, I couldn’t define the column mapping for an embedded class (where instead of mapping classes onto separate tables a class can be “embedded” within the current table).

I had hoped it would be a straight forward as defining the column mappings in the embedded class definition, but unfortunately not. Any mappings appear to be ignored.

I tried in the embedding class. No. I even experimented with the embedded property, but that was a long shot I didn’t expect to work anyway.

It would seem I will have to define the mapping in the old fashioned hibernate configuration file way.

One useful thing I did find in this frustrating experiment is that the configuration setting …
dataSource {
logSql = "true"
}

… provides a more readable format than …
hibernate {
show_sql = "true"
}

Not a total loss then!

Comments
1 Comment »
Categories
development
Tags
db, gorm, grails, hibernate, sql
Comments rss Comments rss
Trackback Trackback

Grails on an existing database

Ian | May 19, 2008

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

« 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 (37)
  • miscellaneous (28)
  • music (7)
  • software (19)

What I'm Doing...

  • @noelfielding11 why are you in watching telly!? in reply to noelfielding11 2010-04-16
  • What was so good about Nick Drake? These "artists" are covering, music is spot on but no effect at all. Totally lacking the goose pimples. 2010-04-16
  • Some Ginger bloke's on telly covering Nick Drake in a mediocre style. 2010-04-16
  • More updates...

Posting tweet...

Powered by Twitter Tools.

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 css db eclipse esb festivals freesat gorm grails groovy hd hibernate htpc 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 vmc web wordpress xml xpath xslt
rss Comments rss valid xhtml 1.1 design by jide powered by Wordpress get firefox