Tuesday, April 13, 2010

Unit testing Grails Controller - Part - 1

Recently I have been experimenting a lot with grails.

One most import language/framework feature that attracts me is "how easily can we right good unit tests".  As the quality of unit tests will in turn determine the quality of production code.  

Hence, here's my attempt to explain how one can write good Grails Controller tests.

In a grails controller mostly we would be doing any of the following things
Today I am going to cover the first scenario i.e. "Redirect a user to a different action" and we will see how easy it is to write its Unit test case.

For simplicity I am taking an example of a controller that performs CRUD on Person domain object lets call it PersonController

Requirement:    
Whenever user tries to view the index action on PersonController he should be redirected to list action (which shows the list of people)

Controller Code:
Controller code that does the job for us is as follows

Test case class:
Grails Testing Plugin provides excellent support to test controller methods.  Unit test for the above method could be written as follows

Explanation:
Grails is a framework that makes heavily use of Convention over Configuration.  This principal is applied to unit test cases as well.  There are a few things special about the above unit test case.
  • Name of the test case PersonControllerTests
    • This means that the name of controller class under test is PersonController.
    • Although we could have named the test class anything and explicitly mention the controller class under test is PersonController.  However, I am not going to show how that's done in this post as I want to keep this post as simple as possible.
  •  It extends from ControllerUnitTestCase 
    • This automatically initializes controller property of the ControllerUnitTestCase.  This property will be initialized with an instance of PersonController class.
    • Base class also adds dummy dynamic methods like "render" and "redirect" to the PersonController class.  These methods are usually available only in Grails environment
    • Base class also adds members like "params", "redirectArgs", "flash", "modelAndView" etc. to the controller instance
    • Base class tearDown method removes the dummy dynamic render and redirect methods from the PersonController class.
The index action of PersonController class simply redirects the user to list action.

As explained earlier the base class ControllerUnitTestCase adds dummy dynamic redirect method to the PersonController class.  The dummy redirect method simply inserts all arguments passed as key value pairs in the redirectArgs map.  redirectArgs is a Map member property added by ControllerUnitTestCase to the PersonController.

Hence the statement that asserts "index action redirect to list action" would look like

We can easily make out that writing good Unit test is extremely easy in  Grails.  We did not have to deal with mocked HTTP requests or responses to test the redirect behavior. 

In next blogs I would show how easily we could write unit tests for the following

As usual your feedback/comments are highly appreciated.
Have some Fun!