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

Selenium RC in the build

August 11, 2008 | 4:19 pm

I had to rediscover a bit of lost knowledge last Friday, namely integrating Selenium RC into a set of integration tests. Pretty straight forward really, but I thought I’d better record it for the next time I can’t remember how to start and stop the server from ant.

<project name="Selenium RC Server">

	<target name="start_selenium_rc" description="Start the Selenium RC server">
		<java
			jar="selenium-server.jar"
			fork="true" failonerror="true">
			<arg value="-Port" />
			<arg value="4440" />
			<arg value="-forcedBrowserMode" />
			<arg value="*iehta" />
		</java>
	</target>

	<target name="stop_selenium_rc" description="Stop the Selenium RC server">
		<get taskname="selenium-shutdown"
			src="http://localhost:4440/selenium-server/driver/?cmd=shutDown"
			dest="junit_report/result.txt" ignoreerrors="true" />
	</target>

</project>

The forced browser mode is IE for project constraints, but I did have an issue with *iexplore not working due to some proxy error but the experimental “elevated security privilege” browser worked fine.

Not so fine is that the goBack() command does not work in SeleniumRC with “*iehta”.

Comments
No Comments »
Categories
development
Tags
ant, java, selenium, testing
Comments rss Comments rss
Trackback Trackback

This week I have mostly been reading…

May 18, 2008 | 11:59 pm

I read an great article Gin, Television, and Social Surplus via eirikso.com, that I was determined to post on but haven had the chance. To much watching TV no doubt!

I have some fun playing with a this java testability explorer from a guy called Misko Hevery.

Then a I had a frustrating delve back into J2ME with a little help from J2ME and My RAZR and in particular this Guide to getting started in J2ME for the Motorola v3x phone. Though I must admit that the bundled MOTODEV Studio for Java ME v1.3 from The Motorola developer network covers pretty much everything.

In the end I was just let down with unlocking my phone. I’ll give it another go, but I’m not holding my breath. Perhaps this Motorola V3 RAZR Unlocking Kit might help. If it’s as straight forward via Blue Tooth as instructions in this post suggest, I’ll eat my hat! I hate it when technology you pay good money for is senselessly hobbled.

Comments
No Comments »
Categories
development, miscellaneous
Tags
j2me, java, razr, testing, tv
Comments rss Comments rss
Trackback Trackback

Please test responsibly

April 24, 2008 | 12:57 pm

As my dentist is persistently asking me, “is it safe?”…

Having been asked to make some enhancements to an existing on-line application, I checked out the code from source control and made my way to the tests. Well you would wouldn’t you!

Selecting the root of the test source, I right clicked and selected run as JUnit test.

It was horrible; like a train crash or something.

After about an hour, I’d removed the errors my correcting path’s and references in the configuration. Unfortunately, I wasn’t in a position to address all the failures since I didn’t know what was bad tests and what was bad code. (Though since the application was live, with no outstanding bugs, it seemed reasonable to assume that the tests were stale.)

Within the tests I was disappointed, though not overly surprised, to find database dependencies to a database on some server. Luckily, the server and the database instance still existed, but I wasn’t really sure what it was used for.

A couple of days after tiding up the tests I was tracked down by team maintaining the mail servers. It appeared that the application I was looking into had been firing emails off to now defunct addresses that were collecting in their dead letter box.

Mixing unit and integration tests is not big and it’s not clever. Dependencies like these may seem reasonable to the developer in the heat of implementation, but they are not safe and make the subsequent support or enhancement of that software much more difficult.

Please test responsibly.

I’ve borrowed the Marathon Man image from this post from Freddo Fungus.

Comments
No Comments »
Categories
development
Tags
java, junit, testing
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