Grails - Testing Controllers

Unit & Integration Testing Controllers

Unit Testing

Basically the same thing as below, however the database will not be started.

Integration Testing

The shortest way to write an integration test for a controller is to extend the grails.test.ControllerUnitTestCase class. In its setUp() method, it creates an instance of your controller class with all the dynamic methods already injected.

For this to work, you must follow the following convention:

  • Your test class needs to be in the same package as the controller class under test
  • The name of your test class needs to be "<YourControllerName>Tests"
Essentially Grails automatically configures each test with a mock request, response, and session which you can then use to perform your tests. For example consider the following controller:
package com.acme.sampleapp

class FooController {

def someRender = { render "bar" }

def someRedirect = { redirect(action:"bar") } }

The tests for this would be:
package com.acme.sampleapp  // must be the same package!

class FooControllerTests extends grails.test.ControllerUnitTestCase {

void testSomeRender() { controller.someRender() assertEquals "bar", controller.response.contentAsString }

void testSomeRedirect() { controller.someRedirect() assertEquals "bar", controller.redirectArgs.action } }

In the above case the response is an instance of MockHttpServletResponse which we can use to obtain the {{contentAsString}} (when writing to the response).

Integration Tests for Controllers with Services

If your controller references a service (or other injected bean), you have to explicitly initialise the service from your test. e.g.

class FilmStarsController {
    def popularityService

def update = { // do something with popularityService }

}

In your test you need to set the service as below

class FilmStarsControllerTests extends grails.test.ControllerUnitTestCase {
  def popularityService

public void testInjectedServiceInController () { controller.popularityService = popularityService controller.update() } }

How the mock request & response work

ControllerUnitTestCase.setup() calls mockController() which in turn calls grails.test.MockUtils.mockController(). If you want to understand where the magic properties named renderArgs, redirectArgs, etc. come from and how they work, learn from the source code of the grails.test.MockUtils class.