Antoine
Antoine

Reputation: 5198

Extending Grails mocking for unit tests (createCriteria, withNewSession, etc...)

As part of a Grails project, I'm currently extending my test suite to stuff that need a complete environment to run, like for instance custom HQL and criteria queries, session related issues, etc. I'm using integration tests.

We already have a fairly large number of unit tests (> 500), where we used to mock methods that don't have a Grails mocked counterpart by default (like withCriteria, withNewSession, etc.) using helper functions like this one:

static mockCriteria(Class clazz, returnValue)
{
  def myCriteria = new Expando()
  myCriteria.list = {Closure cls -> returnValue}
  myCriteria.get = {Closure cls -> returnValue}
  clazz.metaClass.static.createCriteria = { -> myCriteria }
}

Code could then be tested like this:

mockCriteria(MyClass, [result])
assert myClass.createCriteria.list({ ... }) == [result]

Until now I always managed to meet my needs using this approach.

Now I want to add integration tests that actually check how methods that use criterias and HQL queries behave, in order to facilitate refactoring these queries. I'm stuck by the fact that createCriteria is replaced in my tests and don't recover their initial code after the unit tests phase, preventing me from testing them in the integration phase.

How do you address the problem of mocking criteria (or HQL queries, etc.), while allowing to get the original behavior back in integration tests?

EDIT: Unfortunately, upgrading to Grails 2 is not an option.

Upvotes: 2

Views: 1509

Answers (2)

Sr. Oshiro
Sr. Oshiro

Reputation: 160

Try this:

void setUp() {
    super.setUp()
    registerMetaClass MyClass
}

Under the Hood

def a = [1, 2, 3]
def oldMetaClass = ArrayList.metaClass
ArrayList.metaClass.find = { Closure cls -> 5 }
assert 5 == a.find{ it == 1}

ArrayList.metaClass = oldMetaClass  
assert 1 == a.find{ it == 1 }

And for mockCriteria take a look

https://github.com/fabiooshiro/plastic-criteria

(works with 1.3.7)

Upvotes: 1

Victor Sergienko
Victor Sergienko

Reputation: 13475

I rather mock not criterias, but domain methods that use them.

Plus, Grails 2.0 promise to have criteria support in unit tests - not HQL, though.

Upvotes: 1

Related Questions