Monday, March 15, 2010

Grails Goodness: Using MetaClass with Testing

We can use the metaClass property of classes to define behavior we want to use in our tests. But if we do, the change is not only for the duration of a test method, but for the entire test run. This is because we make a change at class level and other tests that use the class will get the new added behavior. To limit our change to a test method we first use the registerMetaClass() method. Grails will remove our added behavior automatically after the test method is finished.

Let's see this with an example. We have a domain class User which uses the Searchable plugin. This plugin will add a search() and we want to use in our test case.

class User {
    static searchable = true
    String username

class UserTests extends GrailsUnitTestCase {
    void testSearch() {
        registerMetaClass User
        User.metaClass.static.search = { searchText ->
            [results: [new User(username:'mrhaki')],
             total: 1, offset: 0, scores: [1]] 
        assertEquals 'mrhaki', User.search('mrhaki').results[0].username