Thursday, June 4, 2009

Integration Testing Grails Controllers

If you are planning on running integration tests on your Grails controllers it would be good to know how to test your controller regardless of whether it simply returns the model or uses the render method.

When your controller returns a model you can simply test the return type.

Given:

def show = {
def bookInstance= Book.get( params.id )
return [ bookInstance: bookInstance] }
}


You test it by:

def model = myController.show()
assertNotNull model.bookInstance

or some such.

If you use the render method in your controller then you would use the ModelAndView object in your controller.

Given:

def save = {
def bookInstance = Book.get(params.id)
render(view:'create',model: [ bookInstance : bookInstance ])
}

You can test it as follows:

bookController.save()
assertNotNull bookController.modelAndView.model.bookInstance

There is one nasty caveat to the render method, and that is if you are rendering a template instead of a view. This is common when you are doing AJAX type calls that only return a partial page. The problem is that Grails will not populate the modelAndView map at all. Nor does render provide a return type.

The answer came from the following mailing list posting:

http://www.nabble.com/Testing-Controller-with-render(template:....)-td18757149.html

Essentially you need to alter the behavior of the render method. You can do this in the setup as follows:

def renderMap

protected void setUp() {
super.setUp()
BookController.metaClass.render = { Map map ->
renderMap = map
}
}


Then Given:


def bookSummary = {
def bookInstance = Book.get(params.id)
render(template: "bookSummary", model: [ bookInstance : bookInstance ])
}


And then you test your model values as follows:

bookController.bookSummary()
assertNotNull renderMap.model.bookInstance

I hope this is helpful.

Happy Grailing!

8 comments:

Amit said...

Thanks a ton!! I was looking for the same for almost two days...

Amit said...
This comment has been removed by the author.
paras said...

This is the gr8.Thanks alott

Prashant Gupta said...

Thanx a ton!

Unknown said...

Great, It helps me alot.

Unknown said...
This comment has been removed by the author.
Unknown said...

I am getting an exception when i try to run my Specification :

class AddressBookControllerSpec extends IntegrationSpec{

AddressBookController addressBookController = new AddressBookController()

void setup() {

}

def "editContact action renders view with addressBook details"() {
when:
addressBookController.editContact()
then:
addressBookController.modelAndView.model.addressBook
}

void cleaup() {
// Tear down logic here
}
}

Exception is:
Running 2 spock tests... 1 of 2
| Failure: editContact action renders view with addressBook details(packagename.AddressBookControllerSpec)
| java.lang.NullPointerException: Cannot get property 'model' on null object
at packagename.AddressBookControllerSpec.setup(AddressBookControllerSpec.groovy:15)
| Completed 2 spock tests, 1 failed in 660ms

Unknown said...

Hello,
The Article on Integration Testing Grails Controllers is informative. It gives detailed information about it.Thanks for Sharing the information on Integration Test .For More information check the detail on Integration testing check, Software Testing Company

Monkey Search