See the light - agile, industrial strength, rapid web application development made easy

(Quick Reference) # 12.1 Unit Testing - Reference Documentation Authors: Graeme Rocher, Peter Ledbrook, Marc Palmer, Jeff Brown, Luke Daley, Burt Beckwith, Lari Hotari Version: 2.3.8 ## Table of Contents ## 12.1 Unit Testing Unit testing are tests at the "unit" level. In other words you are testing individual methods or blocks of code without consideration for surrounding infrastructure. Unit tests are typically run without the presence of physical resources that involve I/O such databases, socket connections or files. This is to ensure they run as quick as possible since quick feedback is important. #### The Test Mixins Since Grails 2.0, a collection of unit testing mixins is provided by Grails that lets you enhance the behavior of a typical JUnit 3, JUnit 4 or Spock test. The following sections cover the usage of these mixins. The previous JUnit 3-style `GrailsUnitTestCase` class hierarchy is still present in Grails for backwards compatibility, but is now deprecated. The previous documentation on the subject can be found in the Grails 1.3.x documentation You won't normally have to import any of the testing classes because Grails does that for you. But if you find that your IDE for example can't find the classes, here they all are: `grails.test.mixin.TestFor` `grails.test.mixin.Mock` `grails.test.mixin.TestMixin` `grails.test.mixin.support.GrailsUnitTestMixin` `grails.test.mixin.domain.DomainClassUnitTestMixin` `grails.test.mixin.services.ServiceUnitTestMixin` `grails.test.mixin.web.ControllerUnitTestMixin` `grails.test.mixin.web.FiltersUnitTestMixin` `grails.test.mixin.web.GroovyPageUnitTestMixin` `grails.test.mixin.web.UrlMappingsUnitTestMixin` `grails.test.mixin.webflow/WebFlowUnitTestMixin` Note that you're only ever likely to use the first two explicitly. The rest are there for reference. #### Test Mixin Basics Most testing can be achieved via the `TestFor` annotation in combination with the `Mock` annotation for mocking collaborators. For example, to test a controller and associated domains you would define the following:
    @TestFor(BookController)
    @Mock([Book, Author, BookService])
The `TestFor` annotation defines the class under test and will automatically create a field for the type of class under test. For example in the above case a "controller" field will be present, however if `TestFor` was defined for a service a "service" field would be created and so on. The `Mock` annotation creates mock version of any collaborators. There is an in-memory implementation of GORM that will simulate most interactions with the GORM API. For those interactions that are not automatically mocked you can use the built in support for defining mocks and stubs programmatically. For example:

    import grails.test.mixin.TestFor
    import spock.lang.Specification@TestFor(BookController)
    @Mock(Book)
    class BookControllerSpec extends Specification {    void "test search"() {
            given:
            def searchMock = mockFor(SearchService)
            searchMock.demand.searchWeb { String q -> ['first result', 'second result'] }
            searchMock.demand.static.logResults { List results ->  }
            controller.searchService = searchMock.createMock()        when:
            controller.search()        then:
            controller.response.text.contains "Found 2 results"
        }
    }
## 12.1.1 Unit Testing Controllers #### The Basics You use the `grails.test.mixin.TestFor` annotation to unit test controllers. Using `TestFor` in this manner activates the `grails.test.mixin.web.ControllerUnitTestMixin` and its associated API. For example:

    import grails.test.mixin.TestFor
    import spock.lang.Specification@TestFor(SimpleController)
    class SimpleControllerSpec extends Specification {    void "test something"() {
        }
    }
Adding the `TestFor` annotation to a controller causes a new `controller` field to be automatically created for the controller under test. The `TestFor` annotation will also automatically annotate any public methods starting with "test" with JUnit 4's @Test annotation. If any of your test method don't start with "test" just add this manually To test the simplest "Hello World"-style example you can do the following:
    // Test class
    class SimpleController {
        def hello() {
            render "hello"
        }
    }

    import grails.test.mixin.TestFor
    import spock.lang.Specification@TestFor(SimpleController)
    class SimpleControllerSpec extends Specification {    void "test hello"() {
            when:
            controller.hello()        then:
            response.text == 'hello'
        }
    }
The `response` object is an instance of `GrailsMockHttpServletResponse` (from the package `org.codehaus.groovy.grails.plugins.testing`) which extends Spring's `MockHttpServletResponse` class and has a number of useful methods for inspecting the state of the response. For example to test a redirect you can use the `redirectedUrl` property:
    class SimpleController {
        def index() {
            redirect action: 'hello'
        }
        …
    }

    import grails.test.mixin.TestFor
    import spock.lang.Specification@TestFor(SimpleController)
    class SimpleControllerSpec extends Specification {    void 'test index'() {
            when:
            controller.index()        then:
            response.redirectedUrl == '/simple/hello'
        }
    }
Many actions make use of the parameter data associated with the request. For example, the 'sort', 'max', and 'offset' parameters are quite common. Providing these in the test is as simple as adding appropriate values to a special `params` variable:

    import grails.test.mixin.TestFor
    import spock.lang.Specification@TestFor(PersonController)
    class PersonControllerSpec extends Specification {    void 'test list'() {
            when:
            params.sort = 'name'
            params.max = 20
            params.offset = 0
            controller.list()        then:
            // …
        }
    }
You can even control what type of request the controller action sees by setting the `method` property of the mock request:

    import grails.test.mixin.TestFor
    import spock.lang.Specification@TestFor(PersonController)
    class PersonControllerSpec extends Specification {    void 'test save'() {
            when:
            request.method = 'POST'
            controller.save()        then:
            // …
        }
    }
This is particularly important if your actions do different things depending on the type of the request. Finally, you can mark a request as AJAX like so:

    import grails.test.mixin.TestFor
    import spock.lang.Specification@TestFor(PersonController)
    class PersonControllerSpec extends Specification {    void 'test list'() {
            when:
            request.method = 'POST'
            request.makeAjaxRequest()
            controller.getPage()        then:
            // …
        }
    }
You only need to do this though if the code under test uses the `xhr` property on the request. #### Testing View Rendering To test view rendering you can inspect the state of the controller's `modelAndView` property (an instance of `org.springframework.web.servlet.ModelAndView`) or you can use the `view` and `model` properties provided by the mixin:
    class SimpleController {
        def home() {
            render view: "homePage", model: [title: "Hello World"]
        }
        …
    }

    import grails.test.mixin.TestFor
    import spock.lang.Specification@TestFor(SimpleController)
    class SimpleControllerSpec extends Specification {    void 'test home'() {
            when:
            controller.home()        then:
            view == '/simple/homePage'
            model.title == 'Hello World'
        }
    }
Note that the view string is the absolute view path, so it starts with a '/' and will include path elements, such as the directory named after the action's controller. #### Testing Template Rendering Unlike view rendering, template rendering will actually attempt to write the template directly to the response rather than returning a `ModelAndView` hence it requires a different approach to testing. Consider the following controller action:
    class SimpleController {
        def display() {
            render template:"snippet"
        }
    }
In this example the controller will look for a template in `grails-app/views/simple/_snippet.gsp`. You can test this as follows:

    import grails.test.mixin.TestFor
    import spock.lang.Specification@TestFor(SimpleController)
    class SimpleControllerSpec extends Specification {    void 'test display'() {
            when:
            controller.display()        then:
            response.text == 'contents of the template'
        }
    }
However, you may not want to render the real template, but just test that is was rendered. In this case you can provide mock Groovy Pages:

    import grails.test.mixin.TestFor
    import spock.lang.Specification@TestFor(SimpleController)
    class SimpleControllerSpec extends Specification {    void 'test display with mock template'() {
            when:
            views['/simple/_snippet.gsp'] = 'mock template contents'
            controller.display()        then:
            response.text == 'mock template contents'
        }
    }
#### Testing Actions Which Return A Map When a controller action returns a `java.util.Map` that `Map` may be inspected directly to assert that it contains the expected data:
    class SimpleController {
        def showBookDetails() {
            [title: 'The Nature Of Necessity', author: 'Alvin Plantinga']
        }
    }

    import grails.test.mixin.TestFor
    import spock.lang.Specification@TestFor(SimpleController)
    class SimpleControllerSpec extends Specification {    void 'test show book details'() {
            when:
            def model = controller.showBookDetails()        then:
            model.author == 'Alvin Plantinga'
        }
    }
#### Testing XML and JSON Responses XML and JSON response are also written directly to the response. Grails' mocking capabilities provide some conveniences for testing XML and JSON response. For example consider the following action:
    def renderXml() {
        render(contentType:"text/xml") {
            book(title:"Great")
        }
    }
This can be tested using the `xml` property of the response:

    import grails.test.mixin.TestFor
    import spock.lang.Specification@TestFor(SimpleController)
    class SimpleControllerSpec extends Specification {    void 'test render xml'() {
            when:
            controller.renderXml()        then:
            response.text == "<book title='Great'/>"
            response.xml.@title.text() == 'Great'
        }
    }
The `xml` property is a parsed result from Groovy's XmlSlurper class which is very convenient for parsing XML. Testing JSON responses is pretty similar, instead you use the `json` property:
    // controller action
    def renderJson() {
        render(contentType:"application/json") {
            book = "Great"
        }
    }

    import grails.test.mixin.TestFor
    import spock.lang.Specification@TestFor(SimpleController)
    class SimpleControllerSpec extends Specification {    void 'test render json'() {
            when:
            controller.renderJson()        then:
            response.text == '{"book":"Great"}'
            response.json.book == 'Great'
        }
    }
The `json` property is an instance of `org.codehaus.groovy.grails.web.json.JSONElement` which is a map-like structure that is useful for parsing JSON responses. #### Testing XML and JSON Requests Grails provides various convenient ways to automatically parse incoming XML and JSON packets. For example you can bind incoming JSON or XML requests using Grails' data binding:
    def consumeBook(Book b) {
        render "The title is ${b.title}."
    }
To test this Grails provides an easy way to specify an XML or JSON packet via the `xml` or `json` properties. For example the above action can be tested by specifying a String containing the XML:

    import grails.test.mixin.TestFor
    import spock.lang.Specification@TestFor(SimpleController)
    @Mock([Book])
    class SimpleControllerSpec extends Specification {
        void 'test consume book xml'() {
            when:
            request.xml = '<book><title>Wool</title></book>'
            controller.consumeBook()        then:
            response.text == 'The title is Wool.'
        }
    }
Or alternatively a domain instance can be specified and it will be auto-converted into the appropriate XML request:

    import grails.test.mixin.TestFor
    import spock.lang.Specification@TestFor(SimpleController)
    @Mock([Book])
    class SimpleControllerSpec extends Specification {    void 'test consume book xml'() {
            when:
            request.xml = new Book(title: 'Shift')
            controller.consumeBook()        then:
            response.text == 'The title is Shift.'
        }
    }
The same can be done for JSON requests:

    import grails.test.mixin.TestFor
    import spock.lang.Specification@TestFor(SimpleController)
    @Mock([Book])
    class SimpleControllerSpec extends Specification {    void 'test consume book json'() {
            when:
            request.json = new Book(title: 'Shift')
            controller.consumeBook()        then:
            response.text == 'The title is Shift.'
        }
    }
If you prefer not to use Grails' data binding but instead manually parse the incoming XML or JSON that can be tested too. For example consider the controller action below:
    def consume() {
        request.withFormat {
            xml {
                render "The XML Title Is ${request.XML.@title}."
            }
            json {
                render "The JSON Title Is ${request.JSON.title}."
            }
        }
    }
To test the XML request you can specify the XML as a string:

    import grails.test.mixin.TestFor
    import spock.lang.Specification@TestFor(SimpleController)
    class SimpleControllerSpec extends Specification {    void 'test consume xml'() {
            when:
            request.xml = '<book title="The Stand"/>'
            controller.consume()        then:
            response.text == 'The XML Title Is The Stand.'
        }    void 'test consume json'() {
            when:
            request.json = '{title:"The Stand"}'
            controller.consume()        then:
            response.text == 'The JSON Title Is The Stand.'
        }
    }
#### Testing Mime Type Handling You can test mime type handling and the `withFormat` method quite simply by setting the request's `contentType` attribute:
    // controller action
    def sayHello() {
        def data = [Hello:"World"]
        request.withFormat {
            xml { render data as grails.converters.XML }
            json { render data as grails.converters.JSON }
            html data
        }
    }

    import grails.test.mixin.TestFor
    import spock.lang.Specification@TestFor(SimpleController)
    class SimpleControllerSpec extends Specification {    void 'test say hello xml'() {
            when:
            request.contentType = 'application/xml'
            controller.sayHello()        then:
            response.text == '<?xml version="1.0" encoding="UTF-8"?><map><entry key="Hello">World</entry></map>'
        }    void 'test say hello json'() {
            when:
            request.contentType = 'application/json'
            controller.sayHello()        then:
            response.text == '{"Hello":"World"}'
        }
    }
There are constants provided by `ControllerUnitTestMixin` for all of the common common content types as shown below:

    import grails.test.mixin.TestFor
    import spock.lang.Specification@TestFor(SimpleController)
    class SimpleControllerSpec extends Specification {    void 'test say hello xml'() {
            when:
            request.contentType = XML_CONTENT_TYPE
            controller.sayHello()        then:
            response.text == '<?xml version="1.0" encoding="UTF-8"?><map><entry key="Hello">World</entry></map>'
        }    void 'test say hello json'() {
            when:
            request.contentType = JSON_CONTENT_TYPE
            controller.sayHello()        then:
            response.text == '{"Hello":"World"}'
        }
    }
The defined constants are listed below:
Constant | Value
--- | ---
ALL_CONTENT_TYPE | */*
FORM_CONTENT_TYPE | application/x-www-form-urlencoded
MULTIPART_FORM_CONTENT_TYPE | multipart/form-data
HTML_CONTENT_TYPE | text/html
XHTML_CONTENT_TYPE | application/xhtml+xml
XML_CONTENT_TYPE | application/xml
JSON_CONTENT_TYPE | application/json
TEXT_XML_CONTENT_TYPE | text/xml
TEXT_JSON_CONTENT_TYPE | text/json
HAL_JSON_CONTENT_TYPE | application/hal+json
HAL_XML_CONTENT_TYPE | application/hal+xml
ATOM_XML_CONTENT_TYPE | application/atom+xml
#### Testing Duplicate Form Submissions Testing duplicate form submissions is a little bit more involved. For example if you have an action that handles a form such as:
    def handleForm() {
        withForm {
            render "Good"
        }.invalidToken {
            render "Bad"
        }
    }
you want to verify the logic that is executed on a good form submission and the logic that is executed on a duplicate submission. Testing the bad submission is simple. Just invoke the controller:

    import grails.test.mixin.TestFor
    import spock.lang.Specification@TestFor(SimpleController)
    class SimpleControllerSpec extends Specification {    void 'test duplicate form submission'() {
            when:
            controller.handleForm()        then:
            response.text == 'Bad'
        }
    }
Testing the successful submission requires providing an appropriate `SynchronizerToken`:

    import grails.test.mixin.TestFor
    import spock.lang.Specificationimport org.codehaus.groovy.grails.web.servlet.mvc.SynchronizerTokensHolder@TestFor(SimpleController)
    class SimpleControllerSpec extends Specification {    void 'test valid form submission'() {
            when:
            def tokenHolder = SynchronizerTokensHolder.store(session)        params[SynchronizerTokensHolder.TOKEN_URI] = '/controller/handleForm'
            params[SynchronizerTokensHolder.TOKEN_KEY] = tokenHolder.generateToken(params[SynchronizerTokensHolder.TOKEN_URI])
            controller.handleForm()        then:
            response.text == 'Good'
        }
    }
If you test both the valid and the invalid request in the same test be sure to reset the response between executions of the controller:

    import grails.test.mixin.TestFor
    import spock.lang.Specificationimport org.codehaus.groovy.grails.web.servlet.mvc.SynchronizerTokensHolder@TestFor(SimpleController)
    class SimpleControllerSpec extends Specification {    void 'test form submission'() {
            when:
            controller.handleForm()        then:
            response.text == 'Bad'        when:
            response.reset()
            def tokenHolder = SynchronizerTokensHolder.store(session)        params[SynchronizerTokensHolder.TOKEN_URI] = '/controller/handleForm'
            params[SynchronizerTokensHolder.TOKEN_KEY] = tokenHolder.generateToken(params[SynchronizerTokensHolder.TOKEN_URI])
            controller.handleForm()        then:
            response.text == 'Good'
        }
    }
#### Testing File Upload You use the `GrailsMockMultipartFile` class to test file uploads. For example consider the following controller action:
    def uploadFile() {
        MultipartFile file = request.getFile("myFile")
        file.transferTo(new File("/local/disk/myFile"))
    }
To test this action you can register a `GrailsMockMultipartFile` with the request:

    import grails.test.mixin.TestFor
    import spock.lang.Specificationimport org.codehaus.groovy.grails.plugins.testing.GrailsMockMultipartFile@TestFor(SimpleController)
    class SimpleControllerSpec extends Specification {    void 'test file upload'() {
            when:
            def file = new GrailsMockMultipartFile('myFile', 'some file contents'.bytes)
            request.addFile file
            controller.uploadFile()        then:
            file.targetFileLocation.path == '/local/disk/myFile'
        }
    }
The `GrailsMockMultipartFile` constructor arguments are the name and contents of the file. It has a mock implementation of the `transferTo` method that simply records the `targetFileLocation` and doesn't write to disk. #### Testing Command Objects Special support exists for testing command object handling with the `mockCommandObject` method. For example consider the following action:

    class SimpleController {
        def handleCommand(SimpleCommand simple) {
            if(simple.hasErrors()) {
                render 'Bad'
            } else {
                render 'Good'
            }
        }
    }class SimpleCommand {
        String name    static constraints = {
            name blank: false
        }
    }
To test this you mock the command object, populate it and then validate it as follows:

    import grails.test.mixin.TestFor
    import spock.lang.Specification@TestFor(SimpleController)
    class SimpleControllerSpec extends Specification {    void 'test valid command object'() {
            given:
            def simpleCommand = new SimpleCommand(name: 'Hugh')
            simpleCommand.validate()        when:
            controller.handleCommand(simpleCommand)        then:
            response.text == 'Good'
        }    void 'test invalid command object'() {
            given:
            def simpleCommand = new SimpleCommand(name: '')
            simpleCommand.validate()        when:
            controller.handleCommand(simpleCommand)        then:
            response.text == 'Bad'
        }
    }
The testing framework also supports allowing Grails to create the command object instance automatically. To test this invoke the no-arg version of the controller action method. Grails will create an instance of the command object, perform data binding on it using the request parameters and validate the object just like it does in when the application is runnning. See the test below.

    import grails.test.mixin.TestFor
    import spock.lang.Specification@TestFor(SimpleController)
    class SimpleControllerSpec extends Specification {    void 'test valid command object'() {
            when:
            params.name = 'Hugh'
            controller.handleCommand()        then:
            response.text == 'Good'
        }    void 'test invalid command object'() {
            when:
            params.name = ''
            controller.handleCommand()        then:
            response.text == 'Bad'
        }
    }
#### Testing Calling Tag Libraries You can test calling tag libraries using `ControllerUnitTestMixin`, although the mechanism for testing the tag called varies from tag to tag. For example to test a call to the `message` tag, add a message to the `messageSource`. Consider the following action:
    def showMessage() {
        render g.message(code: "foo.bar")
    }
This can be tested as follows:

    import grails.test.mixin.TestFor
    import spock.lang.Specification@TestFor(SimpleController)
    class SimpleControllerSpec extends Specification {    void 'test render message tag'() {
            given:
            messageSource.addMessage 'foo.bar', request.locale, 'Hello World'        when:
            controller.showMessage()        then:
            response.text == 'Hello World'
        }
    }
## 12.1.2 Unit Testing Tag Libraries #### The Basics Tag libraries and GSP pages can be tested with the `grails.test.mixin.web.GroovyPageUnitTestMixin` mixin. To use the mixin declare which tag library is under test with the `TestFor` annotation:

    import grails.test.mixin.TestFor
    import spock.lang.Specification@TestFor(SimpleTagLib)
    class SimpleTagLibSpec extends Specification {    void "test something"() {
        }
    }
Note that if you are testing invocation of a custom tag from a controller you can combine the `ControllerUnitTestMixin` and the `GroovyPageUnitTestMixin` using the `Mock` annotation:

    import spock.lang.Specification@TestFor(SimpleController)
    @Mock(SimpleTagLib)
    class SimpleControllerSpec extends Specification {}
#### Testing Custom Tags The core Grails tags don't need to be enabled during testing, however custom tag libraries do. The `GroovyPageUnitTestMixin` class provides a `mockTagLib()` method that you can use to mock a custom tag library. For example consider the following tag library:

    class SimpleTagLib {    static namespace = 's'    def hello = { attrs, body ->
            out << "Hello ${attrs.name ?: 'World'}"
        }    def bye = { attrs, body ->
            out << "Bye ${attrs.author.name ?: 'World'}"
        }
    }
You can test this tag library by using `TestFor` and supplying the name of the tag library:

    import grails.test.mixin.TestFor
    import spock.lang.Specification@TestFor(SimpleTagLib)
    class SimpleTagLibSpec extends Specification {    void "test hello tag"() {
            expect:
            applyTemplate('<s:hello />') == 'Hello World'
            applyTemplate('<s:hello name="Fred" />') == 'Hello Fred'
            applyTemplate('<s:bye author="${author}" />', [author: new Author(name: 'Fred')]) == 'Bye Fred'
        }
    }
Alternatively, you can use the `TestMixin` annotation and mock multiple tag libraries using the `mockTagLib()` method:

    import spock.lang.Specification
    import grails.test.mixin.TestMixin
    import grails.test.mixin.web.GroovyPageUnitTestMixin@TestMixin(GroovyPageUnitTestMixin)
    class MultipleTagLibSpec extends Specification {    void "test multiple tags"() {
            given:
            mockTagLib(SomeTagLib)
            mockTagLib(SomeOtherTagLib)        expect:
            // …
        }
    }
The `GroovyPageUnitTestMixin` provides convenience methods for asserting that the template output equals or matches an expected value.

    import grails.test.mixin.TestFor
    import spock.lang.Specification@TestFor(SimpleTagLib)
    class SimpleTagLibSpec extends Specification {    void "test hello tag"() {
            expect:
            assertOutputEquals ('Hello World', '<s:hello />')
            assertOutputMatches (/.*Fred.*/, '<s:hello name="Fred" />')
        }
    }
#### Testing View and Template Rendering You can test rendering of views and templates in `grails-app/views` via the `render(Map)` method provided by `GroovyPageUnitTestMixin` :

    import spock.lang.Specification
    import grails.test.mixin.TestMixin
    import grails.test.mixin.web.GroovyPageUnitTestMixin@TestMixin(GroovyPageUnitTestMixin)
    class RenderingSpec extends Specification {    void "test rendering template"() {
            when:
            def result = render(template: '/simple/hello')        then:
            result == 'Hello World!'
        }
    }
This will attempt to render a template found at the location `grails-app/views/simple/_hello.gsp`. Note that if the template depends on any custom tag libraries you need to call `mockTagLib` as described in the previous section. Some core tags use the active controller and action as input. In GroovyPageUnitTestMixin tests, you can manually set the active controller and action name by setting controllerName and actionName properties on the webRequest object:
    webRequest.controllerName = 'simple'
        webRequest.actionName = 'hello'
## 12.1.3 Unit Testing Domains #### Overview The mocking support described here is best used when testing non-domain artifacts that use domain classes, to let you focus on testing the artifact without needing a database. But when testing persistence it's best to use integration tests which configure Hibernate and use a database. Domain class interaction can be tested without involving a database connection using `DomainClassUnitTestMixin`. This implementation mimics the behavior of GORM against an in-memory `ConcurrentHashMap` implementation. Note that this has limitations compared to a real GORM implementation. The following features of GORM for Hibernate can only be tested within an integration test: String-based HQL queries composite identifiers dirty checking methods any direct interaction with Hibernate However a large, commonly-used portion of the GORM API can be mocked using `DomainClassUnitTestMixin` including: Simple persistence methods like `save()`, `delete()` etc. Dynamic Finders Named Queries Query-by-example GORM Events If something isn't supported then `GrailsUnitTestMixin`'s `mockFor` method can come in handy to mock the missing pieces. Alternatively you can write an integration test which bootstraps the complete Grails environment at a cost of test execution time. #### The Basics `DomainClassUnitTestMixin` is typically used in combination with testing either a controller, service or tag library where the domain is a mock collaborator defined by the `Mock` annotation:

    import grails.test.mixin.TestFor
    import spock.lang.Specification@TestFor(BookController)
    @Mock(Book)
    class BookControllerSpec extends Specification {
        // …
    }
The example above tests the `SimpleController` class and mocks the behavior of the `Simple` domain class as well. For example consider a typical scaffolded `save` controller action:
    class BookController {
        def save() {
            def book = new Book(params)
            if (book.save(flush: true)) {
                flash.message = message(
                        code: 'default.created.message',
                        args: [message(code: 'book.label', default: 'Book'), book.id])
                redirect(action: "show", id: book.id)
            }
            else {
                render(view: "create", model: [bookInstance: book])
            }
        }
    }
Tests for this action can be written as follows:

    import grails.test.mixin.TestFor
    import spock.lang.Specification@TestFor(BookController)
    @Mock(Book)
    class BookControllerSpec extends Specification {
       void "test saving an invalid book"() {
            when:
            controller.save()        then:
            model.bookInstance != null
            view == '/book/create'
        }    void "test saving a valid book"() {
            when:
            params.title = "The Stand"
            params.pages = "500"        controller.save()        then:
            response.redirectedUrl == '/book/show/1'
            flash.message != null
            Book.count() == 1
        }
    }
`Mock` annotation also supports a list of mock collaborators if you have more than one domain to mock:

    import grails.test.mixin.TestFor
    import spock.lang.Specification@TestFor(BookController)
    @Mock([Book, Author])
    class BookControllerSpec extends Specification {
        // …
    }
Alternatively you can also use the `DomainClassUnitTestMixin` directly with the `TestMixin` annotation and then call the `mockDomain` method to mock domains during your test:

    import grails.test.mixin.TestFor
    import grails.test.mixin.TestMixin
    import spock.lang.Specification
    import grails.test.mixin.domain.DomainClassUnitTestMixin@TestFor(BookController)
    @TestMixin(DomainClassUnitTestMixin)
    class BookControllerSpec extends Specification {    void setupSpec() {
             mockDomain(Book)
        }    void "test saving an invalid book"() {
            when:
            controller.save()        then:
            model.bookInstance != null
            view == '/book/create'
        }    void "test saving a valid book"() {
            when:
            params.title = "The Stand"
            params.pages = "500"        controller.save()        then:
            response.redirectedUrl == '/book/show/1'
            flash.message != null
            Book.count() == 1
        }
    }
The `mockDomain` method also includes an additional parameter that lets you pass a Map of Maps to configure a domain, which is useful for fixture-like data:
    mockDomain(Book, [
                [title: "The Stand", pages: 1000],
                [title: "The Shining", pages: 400],
                [title: "Along Came a Spider", pages: 300] ])
#### Testing Constraints There are 4 types of validateable classes: Domain classes Classes marked with the `Validateable` annotation Command Objects which have been made validateable automatically Classes configured to be validateable via the `grails.validateable.classes` property in `Config.groovy` The first 3 are easily testable in a unit test with no special configuration necessary as long as the test method is marked with `TestFor` or explicitly applies the `GrailsUnitTestMixin` using `TestMixin`. See the examples below.

    // src/groovy/com/demo/MyValidateable.groovy
    package com.demo@grails.validation.Validateable
    class MyValidateable {
        String name
        Integer age    static constraints = {
            name matches: /[A-Z].*/
            age range: 1..99
        }
    }

    // grails-app/domain/com/demo/Person.groovy
    package com.democlass Person {
        String name    static constraints = {
            name matches: /[A-Z].*/
        }
    }

    // grails-app/controllers/com/demo/DemoController.groovy
    package com.democlass DemoController {    def addItems(MyCommandObject co) {
            if(co.hasErrors()) {
                render 'something went wrong'
            } else {
                render 'items have been added'
            }
        }
    }class MyCommandObject {
        Integer numberOfItems    static constraints = {
            numberOfItems range: 1..10
        }
    }

    // test/unit/com/demo/PersonSpec.groovy
    package com.demoimport grails.test.mixin.TestFor
    import spock.lang.Specification@TestFor(Person)
    class PersonSpec extends Specification {    void "Test that name must begin with an upper case letter"() {
            when: 'the name begins with a lower letter'
            def p = new Person(name: 'jeff')        then: 'validation should fail'
            !p.validate()        when: 'the name begins with an upper case letter'
            p = new Person(name: 'Jeff')        then: 'validation should pass'
            p.validate()
        }
    }

    // test/unit/com/demo/DemoControllerSpec.groovy
    package com.demoimport grails.test.mixin.TestFor
    import spock.lang.Specification@TestFor(DemoController)
    class DemoControllerSpec extends Specification {    void 'Test an invalid number of items'() {
            when:
            params.numberOfItems = 42
            controller.addItems()        then:
            response.text == 'something went wrong'
        }    void 'Test a valid number of items'() {
            when:
            params.numberOfItems = 8
            controller.addItems()        then:
            response.text == 'items have been added'
        }
    }

    // test/unit/com/demo/MyValidateableSpec.groovy
    package com.demoimport grails.test.mixin.TestMixin
    import grails.test.mixin.support.GrailsUnitTestMixin
    import spock.lang.Specification
    @TestMixin(GrailsUnitTestMixin)
    class MyValidateableSpec extends Specification {    void 'Test validate can be invoked in a unit test with no special configuration'() {
            when: 'an object is valid'
            def validateable = new MyValidateable(name: 'Kirk', age: 47)        then: 'validate() returns true and there are no errors'
            validateable.validate()
            !validateable.hasErrors()
            validateable.errors.errorCount == 0        when: 'an object is invalid'
            validateable.name = 'kirk'        then: 'validate() returns false and the appropriate error is created'
            !validateable.validate()
            validateable.hasErrors()
            validateable.errors.errorCount == 1
            validateable.errors['name'].code == 'matches.invalid'        when: 'the clearErrors() is called'
            validateable.clearErrors()        then: 'the errors are gone'
            !validateable.hasErrors()
            validateable.errors.errorCount == 0        when: 'the object is put back in a valid state'
            validateable.name = 'Kirk'        then: 'validate() returns true and there are no errors'
            validateable.validate()
            !validateable.hasErrors()
            validateable.errors.errorCount == 0
        }
    }

    // test/unit/com/demo/MyCommandObjectSpec.groovy
    package com.demoimport grails.test.mixin.TestMixin
    import grails.test.mixin.support.GrailsUnitTestMixin
    import spock.lang.Specification@TestMixin(GrailsUnitTestMixin)
    class MyCommandObjectSpec extends Specification {    void 'Test that numberOfItems must be between 1 and 10'() {
            when: 'numberOfItems is less than 1'
            def co = new MyCommandObject()
            co.numberOfItems = 0        then: 'validation fails'
            !co.validate()
            co.hasErrors()
            co.errors['numberOfItems'].code == 'range.toosmall'        when: 'numberOfItems is greater than 10'
            co.numberOfItems = 11        then: 'validation fails'
            !co.validate()
            co.hasErrors()
            co.errors['numberOfItems'].code == 'range.toobig'        when: 'numberOfItems is greater than 1'
            co.numberOfItems = 1        then: 'validation succeeds'
            co.validate()
            !co.hasErrors()        when: 'numberOfItems is greater than 10'
            co.numberOfItems = 10        then: 'validation succeeds'
            co.validate()
            !co.hasErrors()
        }
    }
For validateable classes which are not one of the first 3 types listed above but are configured with the `grails.validateable.classes` property in `Config.groovy`, one additional step is required to test validation. `GrailsUnitTestMixin` provides a method named `mockForConstraintsTests` that will mock validation support for these classes. See the example below.

    // src/groovy/com/demo/Book.groovy
    package com.democlass Book {
        String title
        String author    static constraints = {
            author minSize: 5
        }
    }

    // grails-app/conf/Config.groovy
    grails.validateable.classes = [com.demo.Book]// ...

    // test/unit/com/demo/BookSpec.groovy
    package com.demoimport grails.test.mixin.TestMixin
    import grails.test.mixin.support.GrailsUnitTestMixin
    import spock.lang.Specification@TestMixin(GrailsUnitTestMixin)
    class BookSpec extends Specification {    void 'Test validation'() {
            given:
            mockForConstraintsTests Book        when: 'the author name has only 4 characters'
            def book = new Book()
            book.author = 'Jeff'        then: 'validation should fail'
            !book.validate()
            book.hasErrors()
            book.errors['author'] == 'minSize'        when: 'the author name has 5 characters'
            book.author = 'Jacob'        then: 'validation should pass'
            book.validate()
            !book.hasErrors()
        }
    }
Note that the `mockForConstraintsTests` method changes the behavior of the errors object such that something like `book.errors'author'` will evaluate to the name of the failed constraint, not a `org.springframework.validation.FieldError` object. This is convenient for unit tests. If your unit test really does want a reference to the `org.springframework.validation.FieldError` object use something like `book.errors.getFieldError('author')`. That's it for testing constraints. One final thing we would like to say is that testing the constraints in this way catches a common error: typos in the "constraints" property name which is a mistake that is easy to make and equally easy to overlook. A unit test for your constraints will highlight the problem straight away. ## 12.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 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 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()
    }
## 12.1.5 Unit Testing URL Mappings #### The Basics Testing URL mappings can be done with the `TestFor` annotation testing a particular URL mappings class. For example to test the default URL mappings you can do the following:

    import com.demo.SimpleController
    import grails.test.mixin.TestFor
    import spock.lang.Specification@TestFor(UrlMappings)
    @Mock(SimpleController)
    class UrlMappingsSpec extends Specification {
        // …
    }
As you can see, any controller that is the target of a URL mapping that you're testing must be added to the `@Mock` annotation. Note that since the default `UrlMappings` class is in the default package your test must also be in the default package With that done there are a number of useful methods that are defined by the `grails.test.mixin.web.UrlMappingsUnitTestMixin` for testing URL mappings. These include: `assertForwardUrlMapping` - Asserts a URL mapping is forwarded for the given controller class (note that controller will need to be defined as a mock collaborate for this to work) `assertReverseUrlMapping` - Asserts that the given URL is produced when reverse mapping a link to a given controller and action `assertUrlMapping` - Asserts a URL mapping is valid for the given URL. This combines the `assertForwardUrlMapping` and `assertReverseUrlMapping` assertions #### Asserting Forward URL Mappings You use `assertForwardUrlMapping` to assert that a given URL maps to a given controller. For example, consider the following URL mappings:
    static mappings = {
        "/actionOne"(controller: "simple", action: "action1")
        "/actionTwo"(controller: "simple", action: "action2")
    }
The following test can be written to assert these URL mappings:

    import com.demo.SimpleController
    import grails.test.mixin.TestFor
    import spock.lang.Specification@TestFor(UrlMappings)
    @Mock(SimpleController)
    class UrlMappingsSpec extends Specification {    void "test forward mappings"() {
            expect:
            assertForwardUrlMapping("/actionOne", controller: 'simple', action: "action1")
            assertForwardUrlMapping("/actionTwo", controller: 'simple', action: "action2")
        }
    }
#### Assert Reverse URL Mappings You use `assertReverseUrlMapping` to check that correct links are produced for your URL mapping when using the `link` tag in GSP views. An example test is largely identical to the previous listing except you use `assertReverseUrlMapping` instead of `assertForwardUrlMapping`. Note that you can combine these 2 assertions with `assertUrlMapping`. ## 12.1.6 Mocking Collaborators Beyond the specific targeted mocking APIs there is also an all-purpose `mockFor()` method that is available when using the `TestFor` annotation. The signature of `mockFor` is:
    mockFor(class, loose = false)
This is general-purpose mocking that lets you set up either strict or loose demands on a class. This method is surprisingly intuitive to use. By default it will create a strict mock control object (one for which the order in which methods are called is important) that you can use to specify demands:
    def strictControl = mockFor(MyService)
    strictControl.demand.someMethod(0..2) { String arg1, int arg2 -> … }
    strictControl.demand.static.aStaticMethod {-> … }
Notice that you can mock static as well as instance methods by using the "static" property. You then specify the name of the method to mock, with an optional range argument. This range determines how many times you expect the method to be called, and if the number of invocations falls outside of that range (either too few or too many) then an assertion error will be thrown. If no range is specified, a default of "1..1" is assumed, i.e. that the method must be called exactly once. The last part of a demand is a closure representing the implementation of the mock method. The closure arguments must match the number and types of the mocked method, but otherwise you are free to add whatever you want in the body. Call `mockControl.createMock()` to get an actual mock instance of the class that you are mocking. You can call this multiple times to create as many mock instances as you need. And once you have executed the test method, call `mockControl.verify()` to check that the expected methods were called. Grails mocks also provide a `demandExplicit` method that can be used in place of demand. This will check the mocked class's metaClass and throw an ExplicitDemandException if a method with that name and signature doesn't exist. For example, given the service:
    class MyService {
        def someMethod(String s) { … }
    }
The following mocking works the same as demand
    def strictControl = mockFor(MyService)
    //Works just like the demand method since method signature exists on the class
    strictControl.demandExplicit.someMethod(1) { String arg1  }
While this mocking throws an ExplicitDemandException when the test is run.
    def strictControl = mockFor(MyService)
    //Throws ExplicitDemandException because method signature doesn't exist
    strictControl.demandExplicit.someMethod(1) { String arg1, String arg2  }
Using demandExplicit should be the preferred method for mocking as it is more likely to catch issues when changing method signatures. Use demand when the method to be mocked is added dynamically, otherwise use demandExplicit. Lastly, the call:
    def looseControl = mockFor(MyService, true)
will create a mock control object that has only loose expectations, i.e. the order that methods are invoked does not matter. ## 12.1.7 Mocking Codecs The `GrailsUnitTestMixin` provides a `mockCodec` method for mocking custom codecs which may be invoked while a unit test is running.
    mockCodec(MyCustomCodec)
Failing to mock a codec which is invoked while a unit test is running may result in a MissingMethodException. ## 12.1.8 Unit Test Metaprogramming If runtime metaprogramming needs to be done in a unit test it needs to be done early in the process before the unit testing environment is fully initialized. This should be done when the unit test class is being initialized. For a Spock based test this should be done in the `setupSpec()` method. For a JUnit test this should be done in a method marked with `@BeforeClass`.

    package myappimport grails.test.mixin.*
    import spock.lang.Specification@TestFor(SomeController)
    class SomeControllerSpec extends Specification {
        def setupSpec() {
            SomeClass.metaClass.someMethod = { ->
                // do something here
            }
        }    // …
    }

    package myappimport grails.test.mixin.*
    import org.junit.*@TestFor(SomeController)
    class SomeControllerTests {    @BeforeClass
        static void metaProgramController() {
            SomeClass.metaClass.someMethod = { ->
                // do something here
            }
        }    // ...}
| Quick Reference (hide)