Fork me on GitHub

30 Nov 2010

Encapsulating page state and actions in Geb

Geb Page and Module classes are just regular Groovy classes. In addition to the content DSL you can declare methods just as you would in any other class. Those methods can use content properties directly. This is really useful for encapsulating state and actions in a reusable way.

In this post I want to run through a couple of simple examples of re-usable Module classes that are enhanced with methods. Although the examples deal with Module classes everything here is equally applicable to Page classes.

Page object methods tend to fall into two categories:

Observers
report on some aspect of page state (e.g. whether a user is logged in or not).
have non-void return types (I prefer explicit return types on methods but def would work too).
can be used for making assertions.
Actions
perform an action such as clicking a link or button.
will typically be void (note that it's not necessary to return a Page instance or class from a navigation method in Geb).
throw IllegalStateException if the action is invalid in the current page state.

First let's consider an authentication module that can be used across every page in a site. The markup of the module can be completely different depending on whether a user is logged in or not. When not logged in a username/password form is shown:

<aside id="auth"> 
    <fieldset> 
        <legend>Log In</legend> 
        <form action="/auth/login" method="post" > 
            <label>Username: <input name="username"/></label> 
            <label>Password: <input type="password" name="password"></label> 
            <button name="login" type="submit">Log In</button> 
        </form> 
    </fieldset> 
</aside> 

When logged in, a welcome message is shown:

<aside id="auth"> 
    Welcome back <span class="username">blackbeard</span> 
    <a href="/auth/logout" name="logout">Log Out</a> 
</aside>

To model this I'll create a Geb Module like this:

class AuthModule extends Module {
    static base = { $("aside#auth") }

    static content = {
        username(required: false) { $(".username").text() }
        logoutButton(required: false, to: HomePage) { $("a[name=logout]") }
        form(required: false) { $("form") }
        loginButton(required: false, to: HomePage) { $("button[name=login]") }
    }
}

The required: false declaration is used to declare content properties that may or may not be on the page. The username and logoutButton properties are only present in the logged-in state and the form and loginButton properties are only present in the logged-out state.

I can use the module in some tests like this:

def "user can log in"() {
    when:
    authModule.form.username = "blackbeard"
    authModule.form.password = "yohoho!"
    authModule.loginButton.click()

    then:
    at HomePage
    authModule.username == "blackbeard"
}

def "user can log out"() {
    when:
    authModule.logoutButton.click()

    then:
    at HomePage
    authModule.username == null
}

This is a good start but there are several assumptions and bits of page detail creeping into the test. The test is using the presence or absence of the username to determine if someone is logged in or not. That doesn't lead to a very meaningful assertion in the test and is assuming things about the page detail. Likewise the login step is quite long-winded and likely to be repeated in a lot of tests. Not only that but it won't work if a user is already logged in as the form fields won't be present on the page.

To encapsulate the module's state and actions better I'll add the following methods:

boolean isLoggedIn() { username }

void login(String username, String password = "password") {
    if (loggedIn) throw new IllegalStateException("already logged in")
    form.username = username
    form.password = password
    loginButton.click()
}

void logout() {
    if (!loggedIn) throw new IllegalStateException("already logged out")
    logoutButton.click()
}

The methods declared by the module abstract some detail away very effectively. The isLoggedIn method means I can change the login detection mechanism later and just change the module's method rather than a bunch of tests. The login and logout methods abstract away the how of logging in and out so the test can just deal with the what. I've used IllegalStateException for cases where a method is called when the module is not in the correct state. The tests now look much clearer:

def "user can log in"() {
    when:
    authModule.login "blackbeard"

    then:
    at HomePage
    authModule.username == "blackbeard"
}

def "user can log out"() {
    when:
    authModule.logout()

    then:
    at HomePage
    !authModule.loggedIn
}

Another good example of encapsulating state and behaviour like this is a typical pagination module that would appear on a list or search results page. The markup would look something like this (I've omitted the link href attributes for clarity):

<nav class="pagination">
    <a class="prevLink">Previous</a>
    <a class="step">1</a>
    <span class="currentStep">2</span>
    <a class="step">3</a>
    <a class="nextLink">Next</a>
</nav>

The previous and next links will only appear when there is a previous or next page and no links will be present at all if there is only a single page. The following Module class models the state and actions of this component:

class Pagination extends Module {
    static content = {
        links(required: false) { $("a") }
        currentPage(required: false) { $(".currentStep")?.text()?.toInteger() ?: 1 }
        nextLink(required: false) { links.filter(".nextLink") }
        previousLink(required: false) { links.filter(".prevLink") }
    }

    boolean isFirstPage() {
        previousLink.empty
    }

    boolean isLastPage() {
        nextLink.empty
    }

    void toPage(int pageNumber) {
        def link = links.filter(text: "$pageNumber")
        if (!link) throw new IllegalArgumentException("Page number $pageNumber not present in pagination")
        link.click()
    }

    void nextPage() {
        if (lastPage) throw new IllegalStateException("Already on the last page")
        nextLink.click()
    }

    void previousPage() {
        if (firstPage) throw new IllegalStateException("Already on the first page")
        previousLink.click()
    }
}

Breaking the Module down in detail:

  • The currentPage property returns the current page number as an int and defaults to 1 if there is no pagination present in the page.
  • The isFirstPage and isLastPage observer methods use the absence of the previous and next links respectively to determine if the current page is the first or last one.
  • The toPage method finds a numbered link and clicks it, throwing IllegalArgumentException if no such link is present.
  • The nextPage and previousPage action methods throw IllegalStateException if the relevant link is not on the page.

The Pagination class now neatly encapsulates the detail of the pagination elements and presents a higher-level façade to the tests.

Fuller versions of the examples in this post can be found on GitHub.

26 Nov 2010

Modelling repeating structures with Geb page objects

Geb is the hot new thing in Grails functional testing. One of its most powerful features is the concise DSL for defining page objects. The reasons for using page objects are well enumerated elsewhere but the basic point is to allow your tests to interact with pages in a manner agnostic of the detail of their structure. This is both practical (you can change markup structure without having to fix numerous tests that only fail because they were tightly coupled to that structure) and aesthetic (your tests read more like a user’s interaction with the page - the what rather than the how).

I want to put together a few short blog posts dealing with patterns that I find useful for defining page objects and modules in Geb. As I go I’ll keep adding to a very simple Grails project showing working examples which is available on GitHub.

In this post I want to talk about repeating data structures such as lists and tables and how to model them effectively.

A content property in a Geb Page or Module can be any type; whatever is returned from the defining closure. This will frequently be a Geb Navigator instance or a String but can be whatever is useful for the tests you’re writing. A good rule of thumb is that the test should be dealing with as simplified a view of the data as possible. All the complexity of traversing HTML elements and manipulating them into a useful form should be hidden away in the page objects and modules. When handling repeating data structures such as ol or table elements you probably want to be able to treat the content as a List so that tests can use Groovy features such as iterator methods, indexing and slicing to make very expressive assertions.

Simple repeating structures

For example, imagine we want to verify an ol element like this:

<ol id="recent-books">
    <li>Zero History</li>
    <li>Surface Detail</li>
    <li>The Machine of Death</li>
</ol>

The most useful type would probably be a List<String> which we can get easily enough by defining our content like this:

static content = {
    recentBooks { $("ol#recent-books li")*.text() }
}

This is then very easy to use in a test:

expect:
recentBooks == ["Zero History", "Surface Detail", "The Machine of Death"]

Complex repeating structures using Modules

A more complex example of a repeating structure is a table, where each row contains several fields. Here we can use a Geb Module to represent each row, with content properties to get data from each cell. Let’s say we want to verify the contents of the following table of search results:

<table id="book-results">
    <thead>
        <tr>
            <th>Title</th>
            <th>Author</th>
            <th>Format</th>
            <th>Price</th>
            <th>Release Date</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>Zero History</td>
            <td>William Gibson</td>
            <td>Hardback</td>
            <td>£12.29</td>
            <td>2 Sep 2010</td>
        </tr>
        <tr>
            <td>Zero History</td>
            <td>William Gibson</td>
            <td>Kindle</td>
            <td>£11.99</td>
            <td>2 Sep 2010</td>
        </tr>
        <tr>
            <td>Spook Country</td>
            <td>William Gibson</td>
            <td>Paperback</td>
            <td>£5.00</td>
            <td>31 Jul 2008</td>
        </tr>
        <tr>
            <td>Pattern Recognition</td>
            <td>William Gibson</td>
            <td>Paperback</td>
            <td>£4.99</td>
            <td>24 Jun 2004</td>
        </tr>
    </tbody>
</table>

We can define our module like this:

static content = {
    bookResults { i -> module BookRow, $("table#book-results tbody tr", i) }
}

class BookRow extends Module {
    static content = {
        cell { i -> $("td", i) }
        title { cell(0).text() }
        author { cell(1).text() }
        format { cell(2).text() }
        price { cell(3).text()[1..-1].toDouble() }
        releaseDate { cell(4).text() }
    }
}

The bookResults content closure takes a row number parameter and uses it to select the corresponding tr from the body of the table and use that to construct a module. The module itself defines content properties with meaningful names that map to the text in each cell.

This isn’t bad as far as it goes. We can use the module pretty effectively in tests like this:

expect:
bookResults(0).title == "Zero History"
bookResults(3).price == 4.99

However, bookResults isn’t a List. We can’t easily get all the book titles at once or make an assertion that all the authors are the same or find the lowest price. Even querying how many rows there are would require an additional content property or method to retrieve $("tbody tr").size(). The table is a repeating data structure and it would be nice to treat it as one!

This ought to be possible bearing in mind 3 things:

  1. The type of a content property is simply whatever you return from the defining closure, there’s no reason we can’t return a List<BookRow>.
  2. There’s nothing special about the expression that constructs the module itself: module BookRow, $("tbody tr", i) is just a call to a method called module passing a Class<? extends Module> which is the module type we want and a Navigator pointing to the module’s root element.
  3. The Geb Navigator class returned by the $ expression implements Iterable<Navigator> and can be treated like a List of all the selected HTML elements.

In fact we can get a List<BookRow> easily enough if we redefine the bookResults property like this:

static content = {
    bookResults {
        $("tbody tr").collect {
            module BookRow, it
        }
    }
}

The key here is that we iterate over the tr elements inside the content definition collecting a new BookRow instance for each one. Now the page object doesn’t require the test to pass in the index of the row it’s interested in. This enables our test to do some much more powerful and interesting things:

expect:
bookResults.size() == 4
bookResults[0].title == "Zero History"
bookResults.title.unique() == ["Zero History", "Spook Country", "Pattern Recognition"]
bookResults.every { it.author == "William Gibson" }
bookResults[2..3].every { it.format == "Paperback" }
bookResults.price.sum() == 34.27

I’ve tried to show a couple of reasonably simple examples here. Others are easy to imagine; a Map representing the dt and dd elements inside an HTML definition list, a list of modules representing a group of labelled radio buttons or news items with images and links, a tree-like multi-level navigation structure, etc.

24 Sept 2010

Stubbing access to the g:message tag in unit tests

Grails controllers and tag libs can access any tag as though it were a method. The most common use for this is probably accessing i18n messages via the g:message tag. However, because tag access is magic wired up by Grails it's not available in unit tests without some effort.

This is a perennial nuisance. Not exactly difficult to solve and yet something I find myself solving over and over in different tests and different projects.

I've come up with what I think is a pretty good and re-usable solution. It allows you to specify messages if you want to, or just use the message code if it's not something you care about in a particular test. As an aside, at a unit test level, I think testing that the correct message code is being used is probably the right thing to do; I'd leave testing actual message text to end-to-end tests.

Here's an example. Imagine we're testing the following controller that displays a simple greeting:

Here's a spec that shows the behaviour both when a message is specified and when it isn't:

A few things to note:
  1. The stubbed message tag returns the code if there is no message defined
  2. message arguments are ignored unless there is a message defined

Although in the example I've used Spock, this technique would work equally well with JUnit tests extending ControllerUnitTestCase. It will also work just as well for tag libs tests extending TagLibUnitTestCase or TagLibSpec.

12 Aug 2010

Auto-generate Spock specs for Grails artifacts

When creating artifacts such as domain classes, controllers and tag libs Grails generates a JUnit test case. If, like me, you're digging writing specifications with Spock you'd probably rather have Grails generate one of those. The last thing I want is to manually transform every generated test case into a specification for every artifact I create.

It's very simple to create a CreateUnitSpec or CreateIntegrationSpec script with a template specification. Hooking in to the other types of artifact creation turned out to be fiddlier. Each create-* command calls a Closure called createUnitTest. Reassigning that Closure should be the solution. The trick is in figuring out where that can be done.

Any time one of its Gant targets is invoked the Grails build system fires an event. You can respond to those events by declaring a closure called event<target name>Start in scripts/_Events.groovy. The only Gant target directly invoked when an artifact is created is called 'default'. It is possible to intercept that although that means the event handler will be invoked any time any Gant target called 'default' runs. For this purpose that's no problem since we're just overriding a closure in the build binding.

The other factor is that the superclass for the unit test is specified by the individual create-* scripts (or defaulted to GrailsUnitTestCase). Rather than having to override those scripts as well, I've just mapped the non-standard unit test superclasses to the Spock equivalents.

Here's the code for your _Events.groovy script:
The template specification should be placed in src/templates/artifacts/Spec.groovy and is simply:
It goes without saying that this is a slightly hairy and it would be great if Grails provided a proper hook for overriding the test generation. I can live with some fun-size evil in _Events.groovy for the sake of the convenience of getting template specs for all my artifacts, though.

10 Jul 2010

Rendering Grails Joda-Time date inputs cross browser with HTML5, jQuery and Modernizr

Yesterday I released a new version of the Grails Joda-Time plugin that includes support for the various new date and time input types in the HTML5 standard. Right now only Opera supports these types with proper date-picker type controls, the other browsers just render them as text inputs. However this doesn’t mean you can’t or shouldn’t start using them right away. There’s a very handy JavaScript library called Modernizr that you can use to detect the features supported by the client’s browser and render alternatives using script. In this post I’m going to walk through how to combine the Joda-Time plugin, Modernizr and the jQuery datepicker to render an HTML5 date input field that will bind to a LocalDate property on a domain object.

Install the Joda-Time plugin

If you don’t currently have version 1.1+ of the Joda-Time plugin installed, run grails install-plugin joda-time.

Once the plugin is installed you will need to enable HTML5 support so that data binding will use the HTML5 date/time formats. Simply add the following to your Config.groovy

jodatime.format.html5 = true

Create a domain class with a LocalDate property

For this example I’ll create a simple domain class representing a person:

import org.joda.time.*
import org.joda.time.contrib.hibernate.*

class Person {
    String name
    LocalDate birthdate
    static mapping = {
        birthdate type: PersistentLocalDate
    }
}

If you have default mappings set up (which the Joda-Time plugin will attempt to do for you when it installs) then you can omit the mapping block but I’ve included it for completeness.

Execute grails generate-all Person to create a controller and scaffolded views for the Person class. Finally change the create.gsp and edit.gsp files to use an HTML5 input instead of the standard Grails date picker tag. Replace the <g:datePicker name="birthdate"… with this:

<joda:dateField name="birthdate" value="${personInstance.birthdate}"/>

In the unlikely event that all your site’s visitors are using Opera then your work is done at this point. However right now anyone using another browser will have to type in the birthdate value in the correct format in order to get the forms to submit properly which isn’t the friendliest user experience.

Install jQuery and jQuery-UI

You can include jQuery and jQuery-UI by simply downloading the JavaScript files into your app, or linking to them on Google. Alternatively you can use the Grails plugins. If you want to go the plugin route this is what you will need to do. First install the plugins:

grails install-plugin jquery-ui

The jQuery plugin is installed automatically by the jQuery-UI plugin.

Then you will need to add the libraries to your SiteMesh template (or you could include it just on the relevant pages, it doesn’t matter). Add the following in the head section:

<g:javascript library="jquery" plugin="jquery"/>
<jqui:resources components="datepicker" mode="normal" />

Install Modernizr

Download Modernizr and put it in web-app/js/modernizr. You can link to the script direct from there or define a library by adding this to BootStrap.groovy:

import org.codehaus.groovy.grails.plugins.web.taglib.JavascriptTagLib

class BootStrap {
    def init = { servletContext ->
         JavascriptTagLib.LIBRARY_MAPPINGS.modernizr = ["modernizr/modernizr-1.5.min"]
    }

Then include Modernizr in your SiteMesh template by adding the following in the head section:

<g:javascript library="modernizr"/>

To get Modernizr to work its magic you should add a class="no-js" to the html element at the top of your SiteMesh template. Modernizr will replace this when the document loads with a whole bunch of classes that it uses to detect the various features supported by the browser.

Bind the jQuery-UI datepicker to the field

The last step is to ensure that any time a user hits the page with a browser that doesn’t support a native widget for the date input type they get a jQuery datepicker instead. To do this create a JavaScript file and link to it from your SiteMesh template or the pages using date inputs. The script simply needs to contain the following code:

$(document).ready(function() {
    if (!Modernizr.inputtypes.date) {
        $("input[type=date]").datepicker({dateFormat: $.datepicker.W3C});
    }
});

What this does is create a function that runs on page load that uses Modernizr to determine if the date input type is supported and if not initialises a jQuery-UI datepicker for every <input type="date"… found in the page. The dateFormat argument ensures the jQuery widget will update the input with the correct date format when a value is selected.

It’s that simple. Now the create and edit person pages will use the native date input widget when the visitor’s browser supports one and the jQuery widget when it doesn’t.

So how does it look? Here's a screenshot of the page in Firefox when a visitor has focused the date input:

Here's the same thing rendered in Opera using the native datepicker widget (yes, you could be forgiven for thinking the jQuery version is prettier):

With a little adaptation the same thing can be done for the other input types; month, week, time, datetime and datetime-local. Of those month should work perfectly by adding this to your script:

if (!Modernizr.inputtypes.month) {
    $("input[type=month]").datepicker({dateFormat: 'yy-mm');
}

Other types would require different widgets to enable users to input the time portion of the value. There are several jQuery based options available. Of course, instead of jQuery you could use YUI, script.aculo.us or any other date/time widgets. I’ve gone with jQuery because I’m familiar with it and the initialisation is beautifully simple even if you’ve got a number of different inputs on a page.

29 Jun 2010

Acyclic relationship validation in Grails

A common domain class use-case is for a self-referential relationship that must not be circular (a directed acyclic graph). For example, a Person class may have a parent property that is a many-to-one relationship with another Person instance. However a given Person cannot be his own parent or ancestor.

We're using just such a relationship for trees of pages that inherit certain characteristics from their ancestors. In order to validate that our users aren't setting up circular references I implemented the following constraint:Then I just needed to register my new constraint by adding ConstrainedProperty.registerNewConstraint(AcyclicConstraint.NAME, AcyclicConstraint) to grails-app/conf/spring/resources.groovy. Using the constraint is as simple as this:
class Person {

    String name
    Person parent

    static constraints = {
        parent acyclic: true
    }
}
The constraint can be mixed with others such as nullable: true. The really nice thing is that the constraint implementation doesn't reference any of my domain classes directly, meaning it can be re-used in any other domain class.

When you're using similar validation logic in multiple classes defining a constraint like this is a much better option than using a validator closure and like many things in Grails it turns out to be pretty easy to implement.

24 Jun 2010

Defaulting Joda Time Hibernate Types with Grails

Grails 1.2 added the ability to define default Hibernate mappings that apply to all GORM classes. It turns out this is incredibly useful if you're using Joda-Time types instead of java.util.Date in your domain objects. Previously you had to specify the Hibernate user type for every single field, like this:
import org.joda.time.*
import org.joda.time.contrib.hibernate.*

DateTime dateCreated
DateTime lastUpdated
LocalDate birthday

static mapping = {
    dateCreated type: PersistentDateTime
    lastUpdated type: PersistentDateTime
    birthday type: PersistentLocalDate
}
Now you can just add this to your Config.groovy once and do away with the type mappings in the individual classes:
grails.gorm.default.mapping = {
    "user-type" type: PersistentDateTime, class: DateTime
    "user-type" type: PersistentLocalDate, class: LocalDate
}
Correction: I had previously posted that the method call in the default mapping DSL could be anything, but on further investigation it turns out it has to be user-type. Apologies for the error.

I'll look into the possibility of the Joda-Time plugin doing this itself to make things even easier.

15 Jun 2010

Export Selenium IDE scripts for Grails

Thanks to the documentation provided on Adam Goucher's blog I've created a simple Firefox plugin that extends the Selenium IDE and adds formatters that allow you to export a script as a Grails Selenium RC test case. You have the option of JUnit 3 (extends GroovyTestCase, uses assertEquals) or JUnit 4 (doesn't extend anything, uses annotations and assertThat) formats.

I think everything is working. There are some things I'd still like to do:
  • Custom commands are currently exported as commented out which they don't need to be given Grails Selenium RC test cases can call Javascript extension functions directly.
  • I haven't yet figured out how to output a command such as
    selenium.waitForAlertPresent()
    rather than
    selenium.waitFor {
        selenium.isAlertPresent()
    }

The Firefox plugin is available from Selenium HQ. You will need to have Selenium IDE installed for it to work, obviously. Once installed you should find options
  • Export Test Case As -> Grails Selenium RC (JUnit 3)
  • Export Test Case As -> Grails Selenium RC (JUnit 4)
have been added to Selenium IDE's File menu.

Whilst I would certainly not leave the exported test case as is it's a quick way to get started. From the exported script you can easily refactor out some page objects or helper methods.

28 May 2010

Grails Spring Events Plugin

Following on from my last post I've developed a Grails plugin that packages the asynchronous events behaviour up and adds some extra useful functionality.

In addition to the asynchronous event processing the plugin gives you:
  • A publishEvent method attached to all domain classes, controllers and services.
  • A Hibernate session bound to the listener thread for the duration of the notification so that listeners can access lazy-loaded properties, etc.
  • The ability to have a "retry policy" for certain types of failed notifications on individual listeners. This is particularly useful for listeners that do things like invoking external web-services that may be periodically unavailable.

To install the plugin just use:
grails install-plugin spring-events

The code and some more detailed documentation is on GitHub. I'll be migrating the docs to the plugin's page on grails.org soon.

3 May 2010

Asynchronous application events in Grails

On the project for my current client we've been using JMS in a rather naïve way for some time now. We've also experienced a certain amount of pain getting JMS and ActiveMQ configured correctly. However, all we're really using JMS for is asynchronous event broadcasting. Essentially we have a handful actions such as flushing hardware caches and notifying external systems that take place when a document changes. We don't want these things blocking the request thread when users save data.

After wrestling with JMS one too many times we decided to take a look at Spring's event framework instead. It turns out it's extremely easy to use for these kinds of asynchronous notifications in a Grails application.

Essentially any artefact can publish an event to the Spring application context. A simple publishing service can be implemented like this:
import org.springframework.context.*

class EventService implements ApplicationContextAware {

    boolean transactional = false

    ApplicationContext applicationContext

    void publish(ApplicationEvent event) {
        println "Raising event '$event' in thread ${Thread.currentThread().id}"
        applicationContext.publishEvent(event)
    }
}
So a Grails domain class can then do something like this:
def eventService

void afterInsert() {
    eventService.publish(new DocumentEvent(this, "created"))
}

void afterUpdate() {
    eventService.publish(new DocumentEvent(this, "updated"))
}

void afterDelete() {
    eventService.publish(new DocumentEvent(this, "deleted"))
}
Grails services make ideal ApplicationListener implementations. As services are singleton Spring beans they are automatically discovered by Spring's event system without any configuration required. For example:
import org.springframework.context.*

class EventLoggingService implements ApplicationListener<DocumentEvent> {

    boolean transactional = false

    void onApplicationEvent(DocumentEvent event) {
        println "Recieved event '$event' in thread ${Thread.currentThread().id}"
    }
}
Of course, multiple listeners can respond to the same events.

If you run the code you will notice that by default Spring's event system processes events synchronously. The EventService and ApplicationListener will print out the same Thread id. This is not ideal if any of the listener implementations might take any time. Luckily it's easy to override the ApplicationEventMulticaster bean in resources.groovy so that it uses a thread pool:
import java.util.concurrent.*
import org.springframework.context.event.*

beans = {
    applicationEventMulticaster(SimpleApplicationEventMulticaster) {
        taskExecutor = Executors.newCachedThreadPool()
    }
}
Running the code again will show the event being published in one thread and consumed in another. If you have multiple listeners each one will be executed in its own thread.

Oddly, I would have thought it was possible to override the taskExecutor property of the default ApplicationEventMulticaster in Config.groovy using Grails' property override configuration, but I found the following didn't work:
beans {
    applicationEventMulticaster {
        taskExecutor = Executors.newCachedThreadPool()
    }
}

Selenium RC plugin v1.0

The Selenium RC plugin for Grails has hit version 1.0 with:
  • Firefox 3.6 support
  • grabbing of screenshots on test failures
  • the ability to call JavaScript user extensions on the selenium object as though they were regular Groovy methods
among other features. Check out the documentation at http://robfletcher.github.com/grails-selenium-rc and install with grails install-plugin selenium-rc.

Building your app on Hudson with Multiple Grails versions

For my Grails plugins I generally write a test project (or more than one). I thought it would be useful to be able to run these against multiple versions of Grails on my build server so I can spot any incompatibilities with the versions the plugin is supposed to support.

Using Hudson this turned out to be pretty straightforward.

You will need all the Grails versions you want to test against installed on your Hudson box. I put them in /opt so replace that with wherever you have them in the steps below. Also, if you want the builds to run in parallel and will be running any functional tests you'll need the Hudson Port Allocator plugin.

  • Start by creating a new job in Hudson and choosing "Build multi-configuration project".
  • The configuration dialog has an extra section "Configuration Matrix" where you can set up the different config combinations that will run. We're just interested in varying the Grails version so check the "Axes" and create a new axis named "GRAILS_VERSION" with the different versions you want in the "values" box, e.g. "1.2.0 1.2.1 1.2.2 1.3.0.RC2"
  • Set up your source code repository and build triggers as you would for any other project.
  • If you want to run the builds in parallel and are running any functional tests you will need to make sure that Grails starts up on a unique port. In the "Build environment" section add a new "Plain TCP port" named "GRAILS_PORT". If you're running anything else that needs a port such as a Selenium server you'll need one for that as well.
  • Add an "Execute shell" build step. Unfortunately the Hudson Grails plugin does not allow you to use a variable to specify the Grails version so you'll have to go old-school:
    export GRAILS_HOME=/opt/grails-$GRAILS_VERSION
    export PATH=$GRAILS_HOME/bin:$PATH
    # assign Grails a unique port (you can skip this if you're only running unit/integration tests)
    export JAVA_OPTS="$JAVA_OPTS -Dserver.port=$GRAILS_PORT"
    grails clean
    grails upgrade --non-interactive
    grails test-app --non-interactive
  • Check "Publish JUnit test result report" in the "Post-build Actions" section and specify target/test-reports/*.xml as the "Test report XMLs"

When you run the Hudson job you should see it kick off one sub-job for each Grails version. Each will check out the project, upgrade it to the relevant Grails version and run the tests.

I have my plugin test projects triggered by the plugin build and have them grab the plugin zip itself from the archived artefacts in the plugin's Hudson job. So I've added this before the grails test-app step:
grails install-plugin http://my.hudson.server/hudson/job/my-plugin/lastSuccessfulBuild/artifact/my-plugin-1.0.zip --non-interactive
There's a bug in Grails 1.3.0.RC2 that means you will need to split this into a wget followed by installing the zip from a file path rather than a URL. This is fixed in trunk so won't be a problem in Grails 1.3 final.

If you're using SVN I think you may need to revert any changes the grails upgrade has made to application.properties, etc. otherwise you'll get merge conflicts on the next run. This does not seem to be a problem with Git.

21 Apr 2010

A Grails JUnit 4 test template

Grails 1.3 upgrades the bundles JUnit to the newer JUnit 4 API. However, the test template used to generate classes by the Grails create-* scripts is still very JUnit 3-ish. Here's a replacement that will generate a skeleton test using JUnit 4 conventions:

@artifact.package@import grails.test.*
import org.junit.*
import static org.junit.Assert.*
import static org.hamcrest.CoreMatchers.*
import static org.junit.matchers.JUnitMatchers.*

class @artifact.name@ {
    @Before void setUp() {
    }

    @After void tearDown() {
    }

    @Test void something() {

    }
}

To use this just run grails install-templates then copy the contents over the file src/templates/artifacts/Tests.groovy. You can delete anything else in the src/templates directory that you don't need. Then every time you use a Grails command such as grails create-service foo the generated test will use the JUnit 4 template.

17 Mar 2010

Customising collection binding in Grails

Following up on my earlier post about using custom PropertyEditor implementations to bind association properties I started looking into the options for custom binding one-to-many associations.

For example, tags, as seen on many sites (including Blogger) would typically be modelled as a Set of either String or some kind of Tag domain object. With tag functionality we really don't want to be selecting tags using a multi-select combo box. It would be ridiculously huge and hard to find anything in it. An auto-completer that recognises commas as delimiters would be the way to go. Script.aculo.us has an AJAX Autocompleter that can handle this kind of tokenised input. Similarly, the Grails RichUI plugin offers an autocomplete tag that uses a Yahoo! UI component. There are comparable controls available if you're using jQuery or some other Javascript library. What you will end up with is the browser submitting a single parameter containing a comma-separated String of tag names. The trick is to turn that into a collection of String or Tag domain instances.

For the former case binding is pretty easy. All you need is a property editor that converts a comma-separated String into a Set of String and vice-versa:
Then just register the editor in your PropertyEditorRegistrar implementation:
registry.registerCustomEditor List, "tags", new TagListEditor()

If you've gone the latter route and used a domain object to represent a tag things have been trickier. Grails didn't allow you to register custom property editors against one-to-many association properties as it considered it knew how to handle such binding.

I raised and fixed a Grails issue to allow for registering custom editors on one-to-many properties so from 1.2.2 and 1.3-M2 you will be able to use a property editor something like this:

11 Mar 2010

Grails plugins on Hudson

Yesterday I spent some time setting up Hudson continuous integration build for my various Grails plugins. It was pretty straightforward but I've been asked to document the steps involved.

Each plugin has one or more test applications under test/projects each of which has grails.plugin.location.whatever = "../../.." in BuildConfig.groovy. So each plugin CI build needs to run not only the plugin's own unit tests but any integration and/or functional tests included in the test apps as well.

Hudson plugins

I installed the essential plugins I would need:
  • The Grails plugin makes building Grails projects much easier and allows you to build against multiple versions of Grails.
  • The Git plugin enables Hudson to pull from a Git repository such as GitHub.
  • The GitHub plugin adds links to the GitHub project in the Hudson build.
  • The Chuck Norris plugin encourages you to keep your tests from failing.

Configuring Grails

Under Manage Hudson -> Configure System there is a Grails Builder section where I entered the name and path of the various versions of Grails installed on the build box.

Connecting to GitHub

In the project configuration:
  • I pasted the GitHub project URL in the Github project field (shown if you have the GitHub plugin installed).
  • Under Source Code Management I selected Git then pasted the read-only repository URL into the URL of repository field.
  • I entered master in the Branch Specifier field as I've seen Hudson do odd things picking up changes from other branches before. I don't really need this behaviour and haven't had time to investigate it further yet.
  • I ticked Poll SCM under Build Triggers then set a cron expression of */5 * * * * so Hudson will poll GitHub every 5 minutes.

Grails build steps

  • Select Build with Grails from the Add build step drop down, then:
    • Select the Grails Installation you want to use.
    • Enter the Targets to run. These are the Grails commands that Hudson will execute. For example, I entered "test-app unit: -clean --non-interactive" package-plugin for the to run unit tests then package the plugin. The quotes allow arguments to be passed to individual targets so I'm telling the test-app phase to build clean and run non-interactively (i.e. Grails won't ask about things like installing or uninstalling plugins).
    • The other fields can be left blank for now.
  • Add further Grails build steps for test applications. The only difference in configuring these is that the targets will likely be different and Project Base Directory needs to be set to the relative path where the test apps lives, e.g. test/projects/content-caching

Isolating each build

One thing I found is that it's probably a good idea to specify separate working directory for each build. I found that simultaneous builds would stomp over each other's compiled classes otherwise. This is particularly an issue for me where I have a build for the Selenium RC plugin whilst one of the test apps for the Springcache plugin uses the latest Selenium RC release to run tests.

Hudson provides various environment variables so I just set grails.work.dir to /tmp/.grails/${JOB_NAME} in every case.

The other consideration is the port that Grails applications will use. If you are running any kind of functional tests the Grails application will start and it each Hudson job needs to use a separate server port or simultaneous jobs will experience port contention. The server port is also configured in the Grails build step. I've just assigned a different one to each job but I couldn't think of a particularly clever way to automate the port assignment.

Test reports

Under Post-build Actions I ticked Publish JUnit test result report then entered a comma-separated set of paths to the XML reports generated by each build step. For example, the Springcache plugin has the following reports configured:
target/test-reports/*.xml,test/projects/springcache-test/target/test-reports/*.xml,test/projects/content-caching/target/test-reports/*.xml

That's picking up the root plugin's unit test reports and the reports generated by the springcache-test and content-caching test applications. Hudson does a good job of merging these together into a unified test report.

Running tests that need a browser

Some of my tests use Selenium RC which drives a real browser. Given that Hudson is running on a headless box I had to get the display exported to a box with an X Windows environment.

Still to do

Right now all the plugins are building against Grails 1.2.1 only so the next task is to set up parallel builds using Grails 1.3-RC1. Ideally I would like to use Hudson's multi-configuration project capability to do that but I haven't had a chance to look into it yet. I'd also like to use Gradle to build the various project with one build step but I'd lose the convenience in switching Grails versions that the Hudson Grails plugin gives me.

5 Mar 2010

Page fragment caching with Grails Springcache plugin

Yesterday I released the new version of the Springcache plugin for Grails. The new feature this brings to the table is page fragment caching driven by annotations on controller actions. The feature is based on EhCache Web and is even simpler and more powerful than the full page caching I blogged about recently. With the page fragment caching feature you can:

  • Define @Cacheable and @CacheFlush annotations on controller actions.
  • Have SiteMesh decorate cached and uncached output alike.
  • Use SiteMesh to mix dynamic page sections with cached sections.
  • Use SiteMesh and <g:include> to have multiple areas of the page that are cached and flushed independently of one another.
  • Cache the output of controller actions that use content negotiation separately according to the requested format.

There are some examples in the plugin documentation and the plugin source code has a test project with a variety of page fragment caching mechanisms used and tested.

25 Feb 2010

Using a custom data binder with Grails domain objects

Yesterday I read a post by Stefan Armbruster on how to register a custom data binder to lookup Grails domain objects by any arbitrary property. I wanted to go a little further so that I could not only bind existing domain instances but create new ones as well.

For example, let's say I have Artist and Album domain classes where Artist hasMany Albums and Album belongsTo Artist. Artist has a name property that is unique. On my create album page I want to be able to type in the artist name and have the save action in the controller automatically lookup an existing Artist instance or create a new one if it doesn't exist. Doing this I don't want to have to add or change anything in the save action itself - I could theoretically use dynamic scaffolding.

Adapting Stefan's PropertyEditor implementation I created this:
The crucial change is the if (!value) block which creates the new instance and populates the relevant property.

To make everything work I just need to:
  1. Add the PropertyEditorRegistrar and place it in resources.groovy as per Stefan's post.
  2. Have a text input or autocompleter with the name "artist" in my create album form.
  3. Add artist cascade: "save-update" to the mapping block in Album so that when the Album is saved the new Album will get saved as well.

23 Feb 2010

Full page caching in Grails with Ehcache-Web

I'm on the verge of releasing a new version of the Springcache plugin that will feature a pretty cool new annotation-driven page fragment caching feature based on Ehcache-web. However one of the things that came up during discussions on the mailing list was full page caching. I mentioned that it was pretty straightforward and promised to blog about how to do it, so…

Install Ehcache-web

Add the following to your dependencies in BuildConfig.groovy:
runtime("net.sf.ehcache:ehcache-web:2.0.0") {
 excludes "ehcache-core"
}

Install Grails templates

Run: grails install-templates

Set up a page caching filter

Edit src/templates/war/web.xml and add this to the filters section:
<filter>
 <filter-name>MyPageCachingFilter</filter-name>
 <filter-class>net.sf.ehcache.constructs.web.filter.SimplePageCachingFilter</filter-class>
 <init-param>
  <param-name>cacheName</param-name>
  <param-value>myPageCache</param-value>
 </init-param>
</filter>
And this as the first entry in the filter-mappings section:
<filter-mapping>
 <filter-name>MyPageCachingFilter</filter-name>
 <url-pattern>/controller/action/*</url-pattern>
 <dispatcher>REQUEST</dispatcher>
</filter-mapping>

Configure the cache

Unfortunately you can't configure the cache in grails-app/conf/spring/resources.groovy using EhCacheFactoryBean instances as the servlet filter initialises before the Spring context. The cache definitions need to be added to a ehcache.xml which would normally be placed in grails-app/conf. Here is an example that works for the filter definitions above:
<ehcache>

    <diskStore path="java.io.tmpdir"/>

    <defaultCache
            maxElementsInMemory="10"
            eternal="false"
            timeToIdleSeconds="5"
            timeToLiveSeconds="10"
            overflowToDisk="true"
            />

    <cache name="myPageCache"
           maxElementsInMemory="10"
           eternal="false"
           timeToIdleSeconds="10000"
           timeToLiveSeconds="10000"
           overflowToDisk="true">
    </cache>

</ehcache>

You will need to add another filter and filter-mapping and potentially another cache for each URL pattern you want to cache separately.

Full page caching is fine for simple pages but isn't as flexible as fragment caching. For example, any authenticated state (such as a "Welcome back xxx" label) on the page would get cached across all users. Because Grails uses Sitemesh and has the <g:include> tag for including output from other controllers a fragment caching solution is a good fit. The 1.2 release of the Springcache plugin will add fragment caching functionality. However, I can imagine using full-page caching like this for things like RSS feeds.

17 Jan 2010

A Gradle build for Grails plugins with test apps

There's a fairly popular technique in Grails plugin development where the plugin has 'test apps' stored in test/projects/*, each of which references the plugin by including grails.plugin.location."my-plugin" = "../../.." in its BuildConfig.groovy. Doing this allows you as a plugin developer to:
  • Automate tests for sample projects using the plugin with significantly different configurations.
  • Test using domain classes, controllers, etc. that shouldn't be packaged with the plugin.
  • Test drive, changing code in both the test app and the plugin without the need to use grails package-plugin or grails install-plugin to pick up changes.
The downside is that to run all the plugin project's tests it's necessary to run the plugin's own tests, then change directory into each of the test apps and run their tests. Continuous integration config is also fiddlier for the same reason.

I wanted to find a way to automate this so I could run all my plugins' tests with a single command. I could write a bash script or an Ant build I guess, or even use maven <shudder>. However keeping things in Groovy-land I decided to try using Gradle which I've been meaning to look into for a while now. I saw Hans Dockter's presentation on Gradle at the London Groovy & Grails Exchange back in December and was impressed with how terse and expressive the syntax is, especially compared to XML based formats. Unfortunately one thing Gradle doesn't grok yet is Grails.

The solution I've come up with is based on a post by Helmut Denk on the gradle-user list. Gradle just uses Ant's exec task to shell out and execute the appropriate Grails command. Combining this with Gradle's multi-project build support I now have plugin builds that can be run with gradle test that will automatically descend into the test apps under test/projects/*.

The build.gradle file at the root of the project defines clean and test tasks: The test task will run the plugin's unit tests. The clean task is defined just once for all projects as there's no difference in how it is done - a nice examply of Gradle's DRY-ness.

Then in settings.gradle I tell Gradle where to find the various sub-projects:
Finally each test app has it's own build.gradle that defines its test task: This is only necessary if the test apps run tests differently to the plugin - here my app is running integration rather than unit tests - otherwise I could have defined test in the same DRY manner as clean.

The process is not as fast as it could be if Grails were wired in to Gradle properly. gradle clean test for the Springcache plugin and its two test apps takes just over 2 minutes on my MBP. Also, my Gradle-fu leaves a lot to be desired right now so I'm sure there are improvements that could be made with the way I'm handling the sub-projects. But, for the purposes of a pre-commit test run or Hudson build this works pretty well.

4 Jan 2010

Upgrading Grails 1.1 -> 1.2

We've just successfully upgraded our app from Grails 1.1 to 1.2 and pushed it to our QA environment. I thought I'd write up some of the issues we encountered in case anyone is bashing their heads against them.


Custom constraints that execute queries

Grails 1.2 now executes domain object validation on any unsaved objects when the Hibernate session flushes. One upshot of this is that if you have a custom constraint that executes a query you can end up with a StackOverflowError; the query causes the session to flush, causing the object to be validated, causing the query to run, causing the session to flush, etc.

The solution is to use one of the new domain class dynamic methods withNewSession to execute the query in a separate Hibernate session.

For example, we have a domain class where only a single instance can exist in a 'live' state. A simple unique constraint won't work as any number of instances can exist in other states. The final constraint looks something like this:

static constraints = {
    state validator: { value, self ->
        boolean valid = true
        if (value == State.LIVE) {
            Homepage.withNewSession {
                valid = Homepage.countByStateAndIdNotEqual(State.LIVE, self.id) == 0
            }
        }
        return valid
    }
}

Errors set outside constraints

The new validation on flush behaviour also caused us a more subtle and difficult to trace problem. One of our controllers checks that a date/time property on a domain class instance is in the future when the instance is saved. Doing this in a constraint isn't desirable as it makes it awkward to set up test data or re-save instances in other contexts - the rule really only applies to the domain class when the user creates or updates it on the one particular form.

The validation code in the controller looks something like this:

domainInstance.validate()
if (domainInstance.goLiveTime < new Date()) {
    domainInstance.rejectValue "goLiveTime", "min.notMet"
}
if (!domainInstance.hasErrors() && domainInstance.save()) {
    // redirect
} else {
    // re-render form with errors
}

When upgrading one of our Selenium tests started failing as, although the save was failing, the error message did not get rendered on the form. What was happening is that at the end of the controller action the entity was not saved as it had errors but Hibernate attempted to flush and triggered re-validation which wiped out the error the controller had set.

If save had been called and validation failed then the object would have been made read-only so Hibernate would not attempt to flush it. My solution was to do this explicitly in the else block before rendering the form using GrailsHibernateUtil.setObjectToReadOnly(domainInstance, sessionFactory). It's certainly not ideal that the controller should be aware of this kind of low-level detail so some refactoring is in order here, but it solved the problem.

Specifying fetch modes on associations in criteria queries

We have one particularly nasty query that retrieves a domain object instance and loads an entire hierarchy of associations using several fetchMode "property", FetchMode.JOIN in the criteria query. For example if Author has many books and each Book has many chapters the query previously looked like:

Author.withCriteria {
    // some criteria
    fetchMode "books", FetchMode.JOIN
    fetchMode "chapters", FetchMode.JOIN
}

This always seemed syntactically odd as it appears that chapters is a property of Author when it is in fact a property of each member of Author.books. In Grails 1.2 the syntax makes much more sense as you nest the fetchMode declarations just as you would other criteria. So the example above would become:

Author.withCriteria {
    // some criteria
    fetchMode "books", FetchMode.JOIN
    books {
        fetchMode "chapters", FetchMode.JOIN
    }
}

Date binding format

Date binding now uses a fixed format of yyyy-MM-dd HH:mm:ss.S rather than the short format of the request locale. We have a couple of forms where dates are entered as text rather than using a date picker or rich control and the users (and our tests) expect to be able to enter dates as dd/MM/yy. In order to keep this functionality working I had to create a class that implements PropertyEditorRegistrar and deploy it in grails-app/conf/spring/resources.groovy. The class registers a custom date editor using the required format.

Because the custom property editor registration happens on a per-request basis it would be simple to use the same technique to allow users to enter dates in the locale format they are used to (Americans with their crazy month-day-year format and everyone else with something sensible, for example).

Setting String values in g:set tags

One of the main features of Grails 1.2 is the enhanced GSP rendering performance. One way this was achieved as I understand it is that mutable streams are used rather than immutable String instances where possible. One minor change I had to make to support this was changing g:set tags in the format <g:set var="name">${value}</g:set> to <g:set var="name" value="${value}"/> Variable created in the first manner are now instances of StreamCharBuffer rather than java.lang.String which sometimes caused problems when they were used later.

Flash scope and null values

The flash scope object available to controllers is now an instance of ConcurrentHashMap which means none of its keys can map to null. There were a few places where we were setting flash.message to the result of a method call that might return null. I simply ensured the empty string was used instead.

Ultimately the upgrade took a lot less time and effort than when we went from Grails 1.0.3 to 1.1 and we thankfully didn't encounter any blocking issues. The impression I have is that the platform's really maturing nicely. Will be cool to start using some of the new features of 1.2 in the next few weeks.

2 Jan 2010

Selenium RC tests with a running Grails app

I posted recently about the new remote mode feature of the Selenium RC plugin. One thing I forgot to mention is that this feature can also be used to run your Selenium tests interactively against a running app instance. You can start your app as normal using grails run-app then either open a second terminal or background the process (Ctrl-Z in a bash shell) then use grails -Dselenium.remote=true test-app other:selenium <test name> to run individual tests without stopping or re-starting the app. With the app running development mode you can effectively test-drive using Selenium tests and Grails' artefact reloading capabilities.

One thing I should clarify is that direct domain class access will not work in remote mode. I'm thinking about ways to add fixtures support to the Selenium RC plugin so there's a good alternative approach that will work in remote mode.

1 Jan 2010

Using GMock to complement Grails mockDomain

Since Grails 1.1 we've had pretty good unit testing support via GrailsUnitTestCase and its sub-classes. The mockDomain method is particularly useful for simulating the various enhancements Grails adds to domain classes. However, there are some domain class capabilities, such as criteria queries and the new named queries, that can't really be simulated by mockDomain.

So assuming we're trying to unit test a controller that uses criteria methods or named queries on a domain class how can we enhance the capabilities of mockDomain? One of my favourite Groovy libraries is GMock which I use in preference to Groovy's built in mock capabilities. One of its really powerful features is the ability to use 'partial mocks', i.e. to mock particular methods on a class whilst allowing the rest of the class to continue functioning as normal. This means we can layer a mocked createCriteria, withCriteria or named query call on to a domain class that is already enhanced by mockDomain.

First off you need to add the GMock dependency to your BuildConfig.groovy. Since GMock supports Hamcrest matchers for matching method arguments you'll probably want those as well:
    dependencies {
        test "org.gmock:gmock:0.8.0"
        test "org.hamcrest:hamcrest-all:1.0"
    }
If you're using an earlier version of Grails you'll need to just grab the jar files and put them in your app's lib directory.

Then in your test case you need to import GMock and Hamcrest classes and add an annotation to allow GMock to work:
    import grails.test.*
    import org.gmock.*
    import static org.hamcrest.Matchers.*

    @WithGMock
    class MyControllerTests extends ControllerUnitTestCase {

Adding criteria and named query methods is now fairly simple:

Mocking a withCriteria method

    def results = // whatever you want your criteria query to return
    mock(MyDomain).static.withCriteria(instanceOf(Closure)).returns(results)
    play {
        controller.myAction()
    }
Breaking this example down a little
  1. mock(MyDomain) establishes a partial mock of the domain class.
  2. instanceOf(Closure) uses a Hamcrest instanceOf matcher to assert that the withCriteria method is called with a single Closure argument (the bit with all the criteria in).
  3. returns(results) tells the mock to return the specified results which here would be a list of domain object instances.
In this example we're expecting the withCriteria method to be called just once but GMock supports more complex time matching expressions if the method may be called again.

Mocking a createCriteria method

The withCriteria method returns results directly but createCriteria is a little more complicated in that it returns a criteria object that has methods such as list, count and get. To simulate this we'll need to have the mocked createCriteria method return a mocked criteria object.
    def results = // whatever you want your criteria query to return
    def mockCriteria = mock() {
        list(instanceOf(Closure)).returns(results)
    }
    mock(MyDomain).static.createCriteria().returns(mockCriteria)
    play {
        controller.myAction()
    }
This is only a little more complex than the previous example in that it has the mocked list method on another mock object that is returned by the domain class' createCriteria method. mock() provides an un-typed mock object as we really don't care about the type here.

Mocking a named query

For our purposes named queries are actually pretty similar to createCriteria.
    def results = // whatever you want your criteria query to return
    def mockCriteria = mock() {
        list(instanceOf(Closure)).returns(results)
    }
    mock(MyDomain).static.myNamedQuery().returns(mockCriteria)
    play {
        controller.myAction()
    }

Some other examples:

Mocking a named query with an argument

    mock(MyDomain).static.myNamedQuery("blah").returns(mockCriteria)
For simple parameters you don't need to use a Hamcrest matcher - a literal is just fine.

Mocking a withCriteria call using options

You can pass an argument map to withCriteria, e.g. withCriteria(uniqueResult: true) { /* criteria */ } will return a single instance rather than a List. To mock this you will need to expect the Map as well as the Closure:
    def result = // a single domain object instance
    mock(MyDomain).static.withCriteria(uniqueResult: true, instanceOf(Closure)).returns(result)

Mocking criteria that are re-used

It's fairly common in pagination scenarios to call a list and count method on a criteria object. We can just set multiple expectations on the mock criteria object, e.g.
    def mockCriteria = mock() {
        list(max: 10).returns(results)
        count().returns(999)
    }
    mock(MyDomain).static.myNamedQuery().returns(mockCriteria)

The nice thing about this technique is that it doesn't interfere with any of the enhancements mockDomain makes to the domain class, so the save, validate, etc. methods will still work as will dynamic finders.

Be aware however, that what we're doing here is mocking out the criteria queries, not testing them! All the interesting stuff inside the criteria closure is being ignored by the mocks and could, of course, be garbage. Named queries are pretty easy to test by having integration test cases for your domain class. Criteria queries beyond a trivial level of complexity should really be encapsulated in service methods or named queries and integration tested there. Of course, GMock then makes an excellent solution for mocking that service method in your controller unit test.