The Spock Framework

by Philipp DarkowJuly 31, 2014

Groovy Logo

In one of my current projects, I started to play around with Groovy and was fascinated how groovy this language is. I got more curious about the way to perform testing and started googling around a little bit. My google research showed me several frameworks to test groovy applications. One of these frameworks is the Spock framework. Spock is created for testing Java and Groovy applications. It has a very clear syntax that is easy to read and it comes with a JUnit runner that ensures you can use it with any of your existing tooling. Furthermore, Spock combines the best features of proven tools like JUnit, jMock, and RSpec, and innovates on top of them. In the first part of the blog I am going to explain how you get started with the Spock framework and how a test method looks like. After that I am going to show how you can use Spock with the Geb framework and what the difference is between testing with Spock alone and Spock combined with Geb. In the end a conclusion is given.

The Vocabulary

Spock allows you to write tests as specifications, or more specifically: “Spock lets you write specifications that describe expected features (properties, aspects) exhibited by a system of interest”. In order to write these specifications, you have to use special words to describe these actions. The list below shows all special words with a short explanation.

  • def
    • The entry point of the test method
  • given
    • What is given to perform the test
  • setup
    • The setup that is needed to test the method
  • expect
    • The expected outcome
  • where
    • Can be used to specify variables that are used
  • when
    • Signal word that when a function is called
  • then
    • Signal word what is expected to happened

Getting started

So, let’s start to use the above vocabulary by writing our first test specification:

def “Testing the Controller”() {
    given: "Test creation of the controller"
    def controller = new ExampleController()

    expect: "A new instance of the ExampleController is created"
    controller
}

In this simple test we are testing the creation of a controller. Therefore, we create an instance of the controller in the given block and we expect to have a new instance of this controller. So far our first test specification, which is pretty easy to read. Let’s continue with a slightly more advanced test:

def "update Test"() {
    setup:
    def controller = new ExampleController()
    controller.exampleService = new ExampleService()
    def flashAttributes
    flashAttributes = Mock(RedirectAttributes.class)
    def host = 'www.example.com'

    when: "update the controller"
    controller.update("1", 30, host, flashAttributes)

    then: "expect that the controller is updated"
    1 * flashAttributes.addFlashAttribute('msg', 'Tile 1 updated.')
}

In this test we perform an update on a controller and expect that a flash attribute is added. But let us go through the example line by line (or block by block). In the setup block we create the controller. Because the method that is being tested needs a service, we are going to create the service for the controller. We are expecting that the flash attributes are getting some text added so we need to mock the flash attributes (and yes mocking is also possible with the Spock framework). The host variable is used as a parameter which is needed for the method that gets tested. The next block is the when block. In this block we are going to call the update method of the controller and pass the four arguments to the method.
In the then block we are expecting that the method addFlashAttribute is called exactly one time.

Spock & Geb

Geb is a browser automation solution that we use at Trifork. Spock and Geb play very nicely together, where Geb can help you to test HTTP calls to the server. If you like to know more visit the Geb website and go to the testing part and specifically the integration with Spock. As a small example take a look at the two testing methods:

Spock testing method

def "go to login"() {
    when:
    go "/login"

    then:
    title == "Login Screen"
}

This should look familiar to you but let us check each line shortly. In the first line the test method is declared. The second line contains the when block which performs a call to the login page. In the then block we expect that the title of the page will be “Login Screen” after the call to the login page is performed.

Geb testing method

def "go to login"() {
    when:
    browser.go "/login"

    then:
    browser.page.title == "Login Screen"
}

The Geb variant looks very similar to the Spock variant. In the first line the test method is declared. The when block contains a call to the browser which should open the page /login. The then block expect that the title of the browser page is “Login Screen” now.

So what is the difference between the standalone Spock framework and Spock with Gem? As you can see, the Geb testing method is explicit telling the browser to go to a particular page and that the browser page title should be Login Screen. That is the main difference between those two methods. But what is the advantage of Geb now? You can use Geb without using the Spock framework but then you can’t use the signal words such as when and then.

Conclusion

To conclude, I can say that the “Spock” framework can help with the testing of groovy applications and I hope that I was able to show you how to use it. The syntax is easy to learn, the documentation is quite complete and includes many examples. Just try it out and you will like it 😉