(Quick Reference)

2. Defining The Data - Reference Documentation

Authors: Grails Plugin Collective

Version: 1.0.7

2. Defining The Data

Fixture data is defined using a simple DSL that expresses objects, their properties and their relationships. This is the same DSL used by Grails' Spring BeanBuilder as underneath the covers a BeanBuilder is being used to create the fixture data.

See the section on loading data for information on how to load these definitions.

Here is an overview of the DSL, focussing on features useful for fixture definition.

2.1 Basics

A single object is defined as follows...

gina(Book, title: "Groovy In Action")

This is defining an object named gina, of type Book with the title property set to "Groovy In Action".

An alternative syntax is...

gina(Book) {
    title =  "Groovy In Action"
}

These two syntaxes effectively achieve the same thing. The difference is that the first example is equivalent to...

def gina = new Book(title: "Groovy In Action")

While the second (alternative) syntax is equivalent to...

def gina = new Book()
gina.title = "Groovy In Action"

The two can even be mixed...

gina(Book, title: "Groovy In Action") {
    isbn = "123456778"
}

Specifying Relationships

A key benefit to using the fixtures plugin is that it makes specifying related objects simple and concise.

Consider the following GORM domain classes:

class Author {
    static hasMany = [books: Book]
    String name
}
class Book {
    String title
}

We can specify an Author/Book relationship like so...

b(Book, title: "The Fellowship of the Ring")
a(Author, name: "J.R.R. Tolkien", books: [b])

In this example, b must be defined before it is referenced by a. To reference b before it is defined, the special ref(«name») method can be used...

a(Author, name: "J.R.R. Tolkien", books: [ref("b")])
b(Book, title: "The Fellowship of the Ring")

If the relationship is bidirectional, it can be set on either side...

a(Author, name: "J.R.R. Tolkien")
b(Book, title: "The Fellowship of the Ring", author: a)

2.2 Build-Test-Data Integration

The build-test-data plugin is a great plugin that simplifies specifying test data by populating required properties for you that you don't care about in your particular test.

Consider the following class...

// Book.groovy
class Book {
  String title
  String isbn

static constraints = { title(required: true) isbn(required: true) } }

Whenever an instance of Book is created for a test, the isbn property has to be populated for the object to pass validation which can be distracting if your test does not care about the isbn property. The build-test-data plugin provides a static build() method on all domain classes that creates an instance with all non-specified, mandatory properties filled in with placeholder values that pass constrain tests. For more information, see the documentation on the plugin.

The fixtures plugin integrates with build-test-data by providing a build() method that has the same behaviour as load() except that objects are created via the build-test-data static build() method.

Which means that the following test will pass...

def fixture = fixtureLoader.build {
  gina(Book, title: "Groovy In Action")
}
assert fixture.gina.isbn != null

And is equivalent to...

def gina = Book.build(title: "Groovy In Action")
assert gina.isbn != null

In fixture files, you can specify that build-test-data integration should be used by using the build() method instead of the usual fixture() method.

Switching it on/off

You may only want to define part of your fixture with build-test-data integration, or conversely you may want to define part of it without it. You can do this via the build() and noBuild() methods inside a fixture definition.

fixtureLoader.load {
  build {
    gina(Book, title: "Groovy In Action")
  }
}

fixtureLoader.build {
  noBuild {
    gina(Book, title: "Groovy In Action", isbn: "12345678")
  }
}

Installing build-test-data

Note that build-test-data integration only works if you have installed the build-test-data plugin yourself. The fixtures plugin does not attempt to install it for you.