Music, software, life… and stuff.
[ Twitter ] [ GitHub ] [ Linked In ]
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.
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.
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.

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
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.