views:

19

answers:

1

Is it possible to test the sort 'propertyName' which is defined in the staticMappingBlock

This works during the integration phase but not during the unit phase where my domain has

static mapping = {
    sort 'lastName'
}

void testDefaultSortOrder(){
    def agent1 = new CommissionAgent(firstName: 'fred', lastName: 'b', active:true).save()
    def agent2 = new CommissionAgent(firstName: 'fred2', lastName:'a', active:false).save()

    def agents = CommissionAgent.list()
    assertEquals 'sort order is wrong', agents[0].lastName, agent2.lastName
    assertEquals 'sort order is wrong', agents[1].lastName, agent1.lastName

}

Grails version is 1.3.1

+1  A: 

There isn't any good way to test the actual sorting in unit tests that I'm aware of. What you're trying to test is really such an integral part of the GORM integration that testing it on mocked domain objects, even if they support the sort mapping, doesn't test the actual code that will be run.

The closest thing that you could do in a unit test would be to take a look at the static mapping object to assert that the value of "sort" is set to what you expect it to be.

I put together a blog post a while ago on how to interrogate groovy closures for values. This technique could be used to assert the sort order is set to what you expect like this:

Foo domain object:

package com.example

class Foo {

    String name

    static mapping = {
           sort "name"
    }
}

FooTests unit test:

package com.example

import grails.test.*

class FooTests extends GrailsUnitTestCase {
    void testFooSort() {
         def mappingValues = ClosureInterrogator.extractValuesFromClosure(Foo.mapping)
         assertEquals "name", mappingValues.sort
    }
}

ClosureInterrogator class that allows you to see what a closure does:

package com.example

class ClosureInterrogator {
    private Map closureValueMap = [:]

    static Map extractValuesFromClosure(Closure closure) {
        def interrogator = new ClosureInterrogator(closure)
        return interrogator.closureValueMap
    }

    private ClosureInterrogator(Closure closure) {
        def oldResolveStrategy = closure.getResolveStrategy()
        def oldDelegate = closure.getDelegate()
        closure.delegate = this
        closure.resolveStrategy = Closure.DELEGATE_FIRST

        try {
            closure()
        } finally {        
            closure.setDelegate(oldDelegate)
            closure.setResolveStrategy(oldResolveStrategy)
        }
    }

    // property getter
    def propertyMissing(String name) {
        return closureValueMap[name]
    }

    // property setter
    def propertyMissing(String name, value) {
        closureValueMap[name] = value
    }

    def methodMissing(String name, args) {
        if (args.size() == 1) {
            closureValueMap[name] = args[0]
        } else {
            closureValueMap[name] = args
        }
    }
}
Ted Naleid
I suppose that using this method you could grab the default sort and then apply that sort and see if it matches but that seems overboard, I'm thinking it's just not worth testing in this way. I have integration tests that cover it and since I have other tests that need integration phase it's not just for this test.
dstarh