Fixtures Plugin
The fixtures plugin allows you to easily define a graph of domain objects and save them to the database. You can use this to establish a data set to use while developing your app, or to define common data to use for your integration tests.
Note: The plugin currently does nothing special about tearing down the fixture data.
Creating Fixtures
Fixtures live in the
fixtures directory at the root of your grails project and are groovy scripts. For example,
fixtures/gina.groovy might look like this...
fixture {
guillaume(Author) {
name = "Guillaume Laforge"
}
dierk(Author) {
name = "Dierk Koenig"
}
gina(Book) {
title = "Groovy In Action"
authors = [guillaume, dierk]
}
}Look familiar? Yep, it's the
Spring Bean DSL.
An alternative syntax for defining domain objects is to use Map parameters…
fixture {
guillaume(Author, name: "Guillaume Laforge")
dierk(Author, name: "Dierk Koenig")
gina(Book, title: "Groovy In Action", authors: [guillaume, dierk])
}
Pre/Post Processing
Sometimes it's necessary to do something before or after your fixture is loaded. You can do this by adding
preProcess and/or
postProcess handler.
preProcess {
/* do things before loading fixture */
}fixture {
/* fixture definition */
}postProcess {
/* do things after loading fixture */
}All beans in the application context are available in both pre and post processors…
preProcess {
someService.someMethod()
}Additionally, any object loaded in the fixture is available in the
post processor by name…
fixture {
log(LogMessage) {
message = "something happened"
}
}postProcess {
// change the creation date of the log message
log.dateCreated -= 1
log.save()
}Pre process handlers are executed as soon as they are encountered. However, post processors are
not executed until all fixtures have been loaded (e.g load patterns that match multiple files or fixtures with includes).
Includes
You can include other fixtures from inside a fixture file…
include "parents" // defines “john” and “sue”fixture {
bob(Child) {
father = john
mother = sue
}
}You can include multiple fixtures…
And use ant patterns (see below)…
Loading Fixtures
The fixtures plugin creates a bean called
fixtureLoader that exposes the
load(String[]) method.
def fixture = fixtureLoader.load("gina")You can load multiple fixtures at once by passing more than one fixture file name...
def fixture = fixtureLoader.load("gina", "otherfixture")Beans in different fixture files
can reference each other. As long as the necessary fixtures are loaded, the references will resolve.
Loading via patterns
Ant style path patterns are supported…
fixtureLoader.load("books/*")Integration Tests
The fixtures plugin creates a bean called
fixtureLoader in your grails app which you can use to load fixtures.
class GinaTests extends GroovyTestCase { def fixtureLoader void TestIt() {
fixtureLoader.load("gina")
def gina = Book.findByTitle("Groovy In Action")
assertNotNull(gina)
assertEquals(2, gina.authors.size())
}
}Named Fixtures
Sometimes you want to have the fixture object that you load stick around. For this you can use “named fixtures”…
// load it and name it 'myFixture'
fixtureLoader['myFixture'].load('someFixtureFile')// access it
fixtureLoader['myFixture'].someObjectFromTheFixtureProperty access notation also works…
// load it and name it 'myFixture'
fixtureLoader.myFixture.load('someFixtureFile')// access it
fixtureLoader.myFixture.someObjectFromTheFixtureDevelopment Mode
You can load a development data set in your bootstrap class…
import org.codehaus.groovy.grails.commons.GrailsApplication
import grails.util.GrailsUtilclass BootStrap { def fixtureLoader def init = { servletContext ->
if (GrailsUtil.environment == GrailsApplication.ENV_DEVELOPMENT) {
fixtureLoader.load("gina")
}
} def destroy = {}
}Inline Fixture Definitions
The
fixtureLoader.load() method can also be used to define a one time fixture inline...
def fixture = fixtureLoader.load {
guillaume(Author) {
name = "Guillaume Laforge"
}
dierk(Author) {
name = "Dierk Koenig"
}
gina(Book) {
title = "Groovy In Action"
authors = [guillaume, dierk]
}
}You can post process inline fixtures with Groovy's “with” mechanism…
fixtureLoader.load {
log(LogMessage) {
message = "something happened"
}
}.with {
// change the creation date of the log message
log.dateCreated -= 1
log.save()
}Fixture Objects
The
fixtureLoader.load() method returns a fixture object. This object can be used to load more fixtures or to get at any of the loaded objects.
Loading subsequent fixtures
def fixture = fixtureLoader.load("gina")
fixture.load("otherFixture")Any subsequently loaded fixtures can reference objects from the previous fixture by name…
fixtureLoader.load {
me(Author) {
name = "Luke Daley"
}
}.load {
book(Book) {
title = "Grails Fixtures for Dummies"
authors = [me]
}
}Accessing loaded objects
Loaded objects can be retrieved from the fixture as properties…
def f = fixtureLoader.load {
me(Author) {
name = "Luke Daley"
}
}
assertEquals("Luke Daley", f.me.name)Bidirectional Relationships
When setting bidirectional relationships, be sure to set the property on the owning side of the relationship. That is, the side that
doesn't specify
belongsTo .