Fork me on GitHub

LD.

Music, software, life… and stuff.

[ Twitter ] [ GitHub ] [ Linked In ]

Brute force fixture cleanup in Grails

Feb 19th, 2010 @ 5:09 pm

I am currently working on establishing a suite of functional tests. I am using the functional test features of the spock plugin to do this, which I’ll be writing more on in the near future.

Naturally, I am using the fixtures plugin to load my test data in the functional tests. However, the plugin provides no support for tearing down data. You generally don’t need to worry about this in integration tests because integration tests are by default wrapped in rollback-only transactions. This is not possible due to the nature of functional tests though.

In order to get something up and running quickly, I implemented this…

import groovy.sql.Sql
import grails.plugin.spock.FunctionalSpec

abstract class FunctionalSpecSupport extends FunctionalSpec {

    def dataSource
    def sessionFactory
        
    def cleanup() {
        sessionFactory.currentSession.flush()
        def sql = new Sql(dataSource)
        sql.execute("SET FOREIGN_KEY_CHECKS = 0")
        grailsApplication.domainClasses.each { domainClass ->
            sql.execute "DELETE FROM " + sessionFactory.getClassMetadata(domainClass.clazz).tableName
        }
        sql.execute("SET FOREIGN_KEY_CHECKS = 1")
        sessionFactory.currentSession.clear()
    }
    
}   

All of my actual functional tests extend this FunctionalSpecSupport class. The cleanup() method is to Spock what tearDown() is to standard JUnit tests. That is, it’s invoked after every test. Also, due to historical reasons the project I am working on uses MySQL so the SQL above may be specific to that DB, I don’t know.

That lacks finesse, but it get’s the job done.

Tags: #software  #grails  

Comments

Integration Testing Grails Filters

Feb 16th, 2010 @ 3:54 pm

Grails currently doesn’t ship with any support for testing filters, other than via a functional test. It’s pretty easy to roll your own filter integration tests though.

Here is an example:

import grails.util.GrailsWebUtil

class MyFilterTests extends GroovyTestCase {
    
    def filterInterceptor
    def grailsApplication
    def grailsWebRequest
    
    def request(Map params, controllerName, actionName) {
        grailsWebRequest = GrailsWebUtil.bindMockWebRequest(grailsApplication.mainContext)
        grailsWebRequest.params.putAll(params)
        grailsWebRequest.controllerName = controllerName
        grailsWebRequest.actionName = actionName
        filterInterceptor.preHandle(grailsWebRequest.request, grailsWebRequest.response, null)
    }
    
    def getResponse() {
        grailsWebRequest.currentResponse
    }
    
    def testFilterRedirects() {
        def result = request("home", "index", someParameter: "2")
        assertFalse result
        assertTrue response.redirectedUrl.endsWith(/* something */)
    }
    
}

Note that filterInterceptor.preHandle() executes all of your filters, which is what you really want in an integration test. It also returns the return value of the last executed filter. When issuing a redirect, we return false in our filter handler to prevent any further request processing so we are testing for that here.

If you are interesting in unit testing your filters, you might want to check out the mailing list thread on the topic.

Tags: #grails  #software  

Comments

Dealing with common test support across test types

@ 1:08 pm

Grails ships with several different test superclasses to make your testing life easier. This is great, but what if you have your own common testing bits that you want to provide in a superclass? Even worse, what if you are using the Spock plugin and have a completely different class hierarchy to work with?

The current project I am working on has a mix of Spock and JUnit tests of different types. Most of the tests also require some relatively common context establishment regardless of the test type. The solution I came up with was to use a test support object instead of a super class. That might seem straightforward, but it gets interesting when you need dependency injection.

Let’s take a look at the test support class…

import org.codehaus.groovy.grails.commons.ApplicationHolder

class TestSupport { 
    
    @Lazy fixtureLoader = getBean('fixtureLoader')
    @Lazy someOtherService = getBean('someOtherService')
    
    protected getBean(name) {
        ApplicationHolder.application.mainContext[name]
    }
    
    def loadFixture(fixtureParams) {
        // load fixture here
    }
    
    // Other common methods and stuff
}

Why the use of ApplicationHolder to get at the application context and the beans? Well, we are trying to avoid mixing test and production code by having the TestSupport class in tests/integration, which means we can’t make it a service. We also can’t selectively create an autowired instance via grails-app/conf/resources.groovy because classes in tests/integration are not available to the classloader that deals with loading the application context. So while the use of the static holder bothers me, it’s the only tool we have to get the job done at the moment. Also, not the use of Groovy’s @Lazy transformation.

Here is how I use the test support class in a Spec…

import grails.plugin.spock.*

class SomeSpec extends IntegrationSpec {
    
    @Delegate TestSupport testSupport = new TestSupport()
    
    def "some stuff should happen"() {
        given:
        loadFixture(/* fixture options */)
        when:
        someOtherService.doStuff()
        then:
        someOtherService.stuffHappened
    }
    
    def "some other stuff should happen"() {
        given:
        loadFixture(/* fixture options */)
        when:
        someOtherService.doOtherStuff()
        then:
        someOtherService.otherStuffHappened
    }
}

The use of Groovy’s @Delegate transformation makes the actual test code look like it’s using a support superclass, but it isn’t, which is the whole point of this exercise. You can now use your common test support methods in any kind of test case.

Tags: #grails  #software  

Comments

Panic! At The Disco: Pretty Odd

Feb 13th, 2010 @ 7:03 pm

A very underrated album that kind of slipped past without much fanfare. I despised these guys from their first single. It dropped around the same time My Chemical Romance were getting airplay and there was way too much guyliner and mascara going on. Shitty Emo fashion aside the first album was ok. Not great, but ok. This one really shines though.

It plays like a modern day Sgt. Peppers with solid arrangement and unexpected musicianship. If you enjoy melodically rich tunes and can get past the band’s image and persona then I recommend checking it out.

Tags: #music  

Comments

Providing non-domain validateables in Grails plugins.

Feb 10th, 2010 @ 3:50 pm

Grails now (1.2+) supports making arbitrary classes validateable. This is easy enough, but what if you have a plugin with a non-domain class that needs to be validateable?

What you might try is adding the necessary config into the Config.groovy in your plugin. This is not going to work though because that’s not going to be sourced when your plugin is deployed into an application.

So here’s a solution:

package grails.plugin.radness

class RadnessGrailsPlugin {
    def loadBefore = ['validation'] // important

    def doWithDynamicMethods = {
        if (!application.config.grails.validateable.classes) {
            application.config.grails.validateable.classes = []
        }
        application.config.grails.validateable.classes << RadnessValidateable
    }
}

The RadnessValidateable class gets configured with all the validation bits. You don’t need to annotate the class with org.codehaus.groovy.grails.validation.Validateable, the above is enough to make it work.

Tags: #grails  #software  

Comments

Archive · RSS · Theme by Autumn