About Hubert Ikkink

My name is Hubert A. Klein Ikkink also known as mrhaki. I work at the great IT company JDriven. Here I work on projects with Groovy & Grails, Gradle and Spring. At JDriven we focus on SpringSource technologies. All colleagues want to learn new technologies, support craftmanship and are very eager to learn. This is truly a great environment to work in.

Grails Goodness: Unit Testing Render Templates from Controller

In a previous blog post we learned how we can unit test a template or view independently. But what if we want to unit test a controller that uses the render() method and a template with the template key instead of a view? Normally the view and model are stored in the modelAndView property of the response. We can even use shortcuts in our test code like view and model to check the result. But a render() method invocation with a template key will simply execute the template (also in test code) and the result is put in the response. With the text property of the response we can check the result.

In the following sample controller we use the header template and pass a username model property to render output.

%{-- File: /grails-app/views/sample/_header.gsp --}%
 
<g:if test="${username}">
    <h1>Hi, ${username}</h1>
</g:if>
<g:else>
    <h1>Welcome</h1>
</g:else>
package com.mrhaki.grails.web
 
class SampleController {
 
    def index() {
        render template: 'header', model: [username: params.username]
    }
 
}

With this Spock specification we test the index() action:

package com.mrhaki.grails.web
 
import grails.test.mixin.TestFor
import spock.lang.Specification
 
@TestFor(SampleController)
class SampleControllerSpec extends Specification {
 
    def "index action renders template with given username"() {
        given:
        params.username = username
 
        when:
        controller.index()
 
        then:
        response.text.trim() == expectedOutput
 
        where:
        username || expectedOutput
        'mrhaki' || '<h1>Hi, mrhaki</h1>'
        null     || '<h1>Welcome</h1>'
    }
 
}

Suppose we don’t want to test the output of the actual template, but we only want to check in our test code that the correct template name is used and the model is correct. We can use the groovyPages or views properties in our test code to assign mock implementation for templates. The groovyPages or views are added by the ControllerUnitTestMixin class, which is done automatically if we use the @TestFor() annotation. The properties are maps where the keys are template locations and the values are strings with mock implementations for the template. For example the template location for our header template is /sample/_header.gsp. We can assign a mock String implementation with the following statement: views['/sample/_header.gsp'] = 'mock implementation'

We can rewrite the Spock specification and now use mock implementations for the header template. We can even use the model in our mock implementation, so we can check if our model is send correctly to the template.

package com.mrhaki.grails.web
 
import grails.test.mixin.TestFor
import spock.lang.Specification
 
@TestFor(SampleController)
class SampleControllerSpec extends Specification {
 
    def "index action renders mock template with given username"() {
        given:
        // Mock implementation with escaped $ (\$), because otherwise
        // the String is interpreted by Groovy as GString.
        groovyPages['/sample/_header.gsp'] = "username=\${username ?: 'empty'}"
 
        // Or we can use views property:
        //views['/sample/_header.gsp'] = "username=\${username ?: 'empty'}"
 
        and:
        params.username = username
 
        when:
        controller.index()
 
        then:
        response.text.trim() == expectedOutput
 
        where:
        username || expectedOutput
        'mrhaki' || 'username=mrhaki'
        null     || 'username=empty'
    }
 
}

 

Related Whitepaper:

Java Essential Training

Author David Gassner explores Java SE (Standard Edition), the language used to build mobile apps for Android devices, enterprise server applications, and more!

The course demonstrates how to install both Java and the Eclipse IDE and dives into the particulars of programming. The course also explains the fundamentals of Java, from creating simple variables, assigning values, and declaring methods to working with strings, arrays, and subclasses; reading and writing to text files; and implementing object oriented programming concepts. Exercise files are included with the course.

Get it Now!  

Leave a Reply


eight + 7 =



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.

Sign up for our Newsletter

20,709 insiders are already enjoying weekly updates and complimentary whitepapers! Join them now to gain exclusive access to the latest news in the Java world, as well as insights about Android, Scala, Groovy and other related technologies.

As an extra bonus, by joining you will get our brand new e-books, published by Java Code Geeks and their JCG partners for your reading pleasure! Enter your info and stay on top of things,

  • Fresh trends
  • Cases and examples
  • Research and insights
  • Two complimentary e-books