Login required
Download

Fixtures Plugin

(3)
Author(s): ldaley
Current Release: 1.0-M3
Grails Version: 1.1 > *
Tags domain testing

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…

include "f1", "f2"

And use ant patterns (see below)…

include "books/*"

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'].someObjectFromTheFixture

Property access notation also works…

// load it and name it 'myFixture'
fixtureLoader.myFixture.load('someFixtureFile')

// access it fixtureLoader.myFixture.someObjectFromTheFixture

Development Mode

You can load a development data set in your bootstrap class…

import org.codehaus.groovy.grails.commons.GrailsApplication
import grails.util.GrailsUtil

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