Loading...

May 14, 2013

Grails Goodness: Passing Objects to Attributes of Tags in Unit Tests

Unit testing tag libraries in Grails is easy. We can use the applyTemplate() method to execute a tag and check the output. We pass the HTML string representing the tag to applyTemplate() as we would use it in a GSP. Attribute values of a tag can be String values, but also any other type. To pass other types in our test as attribute values we must add an extra argument to applyTemplate(). The argument is a Map with model values which are used to pass as value to the tag library attributes.

Let's see this in action with an example. First we create a tag library with a tag that will show the value of the title property of a Book instance. The Book instance is passed to the tag as attribute value for the attribute book:

package com.mrhaki.grails

class BookTagLib {

    static namespace = 'book'

    def title = { attributes, body ->
        final Book book = attributes.get('book')
        final String bookTitle = book.title
        out << bookTitle
    }

}

We can test this tag with the following Spock specification. Notice we use the applyTemplate() method and pass an instance of Book using a Map as the second argument:

package com.mrhaki.grails

import grails.test.mixin.TestFor
import spock.lang.Specification

@TestFor(BookTagLib)
class BookTagLibSpecification extends Specification {

    def "show book title for given Book instance"() {
        given:
        final Book book = new Book(title: 'Gradle Effective Implementation Guide')

        expect:
        applyTemplate('<book:title book="${bookInstance}"/>', [bookInstance: book]) == 'Gradle Effective Implementation Guide'
    }

}

Code written with Grails 2.2.2 and Spock 0.7-groovy-2.0.