Login required
Download

Spock

(0)
Author(s): ldaley
Current Release: 0.4-SNAPSHOT
Grails Version: 1.2.0
Tags testing
grails install-plugin spock 0.3-SNAPSHOT
Spock is a testing and specification framework for Java and Groovy applications. What makes it stand out from the crowd is its beautiful and highly expressive specification language. This plugin brings the power of Spock to Grails.

Version 0.3 of this plugin is not compatible with Grails 1.2.0, please use the 0.4-SNAPSHOT version which must be installed with an explicit version number.

If you have any questions or suggestions, please contact us through the Spock discussion forum (or its Nabble mirror). You can also raise an issue in the issue tracker. Sources for the Spock plugin can be found on Google code

Installation

Type: "grails install-plugin spock 0.4-SNAPSHOT"

Appetizer

Here is a very simple Grails unit specification in Spock…

import grails.plugin.spock.*

class MySpec extends UnitSpec { def "domain mocking"() { setup: mockDomain(Person)

when: new Person(name: name).save()

then: Person.findByName(name) != null

where: name = "bill" } }

Before using this plugin, head on over to the Spock project site and get familiar with Spock.

Running Tests

Tests are run just like normal Grails tests via grails test-app . A new “spock” test type is added to the unit, integration and functional phases. You can use the Grails 1.2 test type targeting feature to run only your Spock tests…

grails test-app :spock

Class names of Spock tests must end in either "Spec" or "Specification". Otherwise, the Grails test runner won't find them.

Base Specifications

Several grails specific specification super classes are also provided to make testing your Grails app even easier. These classes for the most part mirror the existing Grails classes such as GrailsUnitTestCase .

All of these classes are in the grails.plugin.spock package.

UnitSpec

The UnitSpec class mirrors the GrailsUnitTestCase class. It features all of the mock* methods that this class has such as mockDomain , mockForConstraintsTests etc.

The example at the start of this page is an example of using UnitSpec .

ControllerSpec

The ControllerSpec class mirrors the ControllerUnitTestCase (+) class. It is a subclass of UnitSpec (so is designed for unit testing) that tests a controller based on the class name. For example, MyControllerSpec will test MyController .

The controller…

class MyController {
  def text = {
    render "text"
  }

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

def bodyElementText = { render request.'XML'.body.text() }

def model = { [a: '1'] } }

The specification…

import grails.plugin.spock.*

class MyControllerSpec extends ControllerSpec {

def 'text action'() { when: controller.text()

then: mockResponse.contentAsString == "text" }

def 'some redirect action'() { when: controller.someRedirect()

then: redirectArgs == [action: "someRedirect"] }

def 'bodyElementText action'() { when: xmlRequestContent = requestContent

and: controller.bodyElementText()

then: mockResponse.contentAsString == value

where: value << ['value', 'value'] requestContent << ["<request><body>value</body></request>", { request { body('value') } }] }

def 'model action'() { expect: controller.model() == [a: '1'] } }

TagLibSpec

The TagLibSpec class is suitable for testing tag libs. It is a subclass of UnitSpec (so is designed for unit testing) that tests a tag lib based on the class name. For example, MyTagLibSpec will test MyTagLib .

The tag lib…

class MyTagLib {
  def bar = { attrs, body ->
    out << "<p>Hello World!</p>"
  }

def bodyTag = { attrs, body -> out << "<${attrs.name}>" out << body() out << "</${attrs.name}>" } }

import grails.plugin.spock.*

class MyTagLibSpec extends TagLibSpec {

def 'bar tag'() { expect: bar() == "<p>Hello World!</p>" }

def 'bar tag subsequent call'() { expect: bar() == "<p>Hello World!</p>" bar() == "<p>Hello World!</p>" }

def 'body tag'() { expect: bodyTag(name: 'a') { "Foo" } == "<a>Foo</a>" bodyTag(name: 'b') { "Bar" } == "<b>Bar</b>" } }

IntegrationSpec

The IntegrationSpec class is the base class for integration tests (i.e. test/integration ). It supports autowiring of beans in the application context…

import grails.plugin.spock.IntegrationSpec

class MyIntegrationSpec extends IntegrationSpec { def myService // will be autowired

/* Spock tests */ }

Like regular Grails integration tests, all tests run in a database transaction that is rolled back. You can disable this behaviour by setting transactional to false…

import grails.plugin.spock.IntegrationSpec

class MyIntegrationSpec extends IntegrationSpec { static transactional = false

/* Spock tests */ }

GroovyPagesSpec

The GroovyPagesSpec is a kind of integration test that is useful for integration test GSP code.

For example:

import grails.plugin.spock.*

class FormatBooleanTagSpec extends GroovyPagesSpec {

def "simple format boolean usage"() { when: template = '<g:formatBoolean boolean="${flag}" true="T" false="F" />' params = [flag: flag] body = null

then: output == letter

where: flag << [true, false] letter << ['T', 'F'] } }

The pattern is always to set template , and optionally params and/or body in the when clause, and then check the output in the then clause.

FunctionalSpec

The FunctionalSpec class can be used to perform functional tests of your application via HTMLUnit

This functional testing features borrow heavily from the grails-functional-test plugin, but is not quite the same.

A big thanks goes out to all who contributed to that plugin, which was the inspiration for these features.

Functional specifications work by providing a session object configured to point at the local grails app. This session object is an instance of grails.plugin.spock.functional.WebSession which is a groovier API to the HTMLUnit class WebClient.

For extra convenience, functional specification automatically delegates method calls and property gets and sets to this session object.

import grails.plugin.spock.*

class MyFunctionalSpec extends FunctionalSpec {

def simpleService // bean properties are autowired

def 'register for something'() { when: get("/registration") form('registrationForm').with { name = "Luke Daley" click 'register' }

then: response.contentAsString =~ 'Thanks for registering' }

}

Documentation on this functional testing is very lacking at the moment. Expect it to improve over the coming days.

For now, you can check out the WebSession source and specification.

Help & Community

Mailing Lists

Consider joining the Spock mailing list to join the Spock community.

Grails specific Spock issues can be raised on that list, or the normal Grails user list.

Reporting Issues

Any issues encountered with either Spock, or this plugin, can be raised in the Spock issue tracker.