Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Grails Goodness: Unit Testing Render Templates from Controller

DZone's Guide to

Grails Goodness: Unit Testing Render Templates from Controller

· Java Zone
Free Resource

Download Microservices for Java Developers: A hands-on introduction to frameworks and containers. Brought to you in partnership with Red Hat.

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 themodelAndView 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 textproperty 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' || '

Hi, mrhaki

' null || '

Welcome

' } }

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. ThegroovyPages 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'
    }

}

Code written with Grails 2.2.4

Download Modern Java EE Design Patterns: Building Scalable Architecture for Sustainable Enterprise Development.  Brought to you in partnership with Red Hat

Topics:

Published at DZone with permission of Hubert Klein Ikkink, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}