Sunday, April 25, 2010

Unit testing Grails Controller - Part - 2

As promised to my readers here's the second installment of Unit testing grails controller.

In my previous post  we had seen how can we test a situation where grails controller redirects user to a different action.

In the post we will focus on how we could test a situation where controller returns a model, which can be used by a view to render itself.

Again, as in the previous post for simplicity I am taking an example of a controller that performs CRUD on Person domain class lets call it PersonController

When user tries to view person's data,  controller should retrieve requested person's information and return it so that view can render itself.

Controller Code:
The controller code would look like

For simplicity I have not shown the code to handle a situations when person with the given id is not found.

How will we test it - How do they do it!:
Clearly, when above code is run in the Grails environment Person.get(personId) will actually fire a database query to get the person.  But when we are unit testing the controller we dont want to fire a database query.  Basically we want to test the PersonController in isolation.

Fortunately, grails provides a method called mockDomain.  This is an extremely powerful method added by the GrailsUnitTestCase class.  As the name suggests, it mock's any grails domain class (as simple as that :)).  This method adds dynamic methods such as save, get, various finder's etc. to Grails domain class.  For e.g. 

will add previously mentioned dynamic methods to Person class.  Which effectively means that we can simulate the behaviour of these methods without actually firing queries agains our database.  Which is what we wanted in the first place!

There are two overloaded versions of mockDomain method

This version behaves as if there are no records in the Person table. 

Second version is

This version behaves as if, each person instance found in the [List of people] represents one record in the person table.  Hence when you call Person.get(123) if the list contained a person with id 123, that person will be returned.

Enough Said!  Show me the code damn it!

The Test case class:
The test case can be written as

Thats all folks!  This is all we need to tests the controller method.

Stay tuned for next installment of Unit Testing Grails Controller!

In this post I have changed my style a little.  Explanation comes before the actual code.  Do give me feedback about this approach which one do you like and why?
Have some Fun!