(Quick Reference)

15.1.4 Unit Testing Filters

Version: 3.2.8

15.1.4 Unit Testing Filters

Unit testing filters is typically a matter of testing a controller where a filter is a mock collaborator. For example consider the following filters class:

class CancellingFilters {
    def filters = {
        all(controller:"simple", action:"list") {
            before = {
                redirect(controller:"book")
                return false
            }
        }
    }
}

This filter interceptors the list action of the simple controller and redirects to the book controller. To test this filter you start off with a test that targets the SimpleController class and add the CancellingFilters as a mock collaborator:

import grails.test.mixin.TestFor
import grails.test.mixin.Mock
import spock.lang.Specification

@TestFor(SimpleController)
@Mock(CancellingFilters)
class SimpleControllerSpec extends Specification {

    // ...

}

You can then implement a test that uses the withFilters method to wrap the call to an action in filter execution:

import grails.test.mixin.TestFor
import grails.test.mixin.Mock
import spock.lang.Specification

@TestFor(SimpleController)
@Mock(CancellingFilters)
class SimpleControllerSpec extends Specification {

    void "test list action is filtered"() {
        when:
        withFilters(action:"list") {
            controller.list()
        }

        then:
        response.redirectedUrl == '/book'
    }
}

Note that the action parameter is required because it is unknown what the action to invoke is until the action is actually called. The controller parameter is optional and taken from the controller under test. If it is another controller you are testing then you can specify it:

withFilters(controller:"book",action:"list") {
    controller.list()
}