Programming for fun and profit

Programming tutorials, problems, solutions. Always with code.

Spock Framework before after class


How to run initialization code before and/or after class/specification in Spock Framework? As always, examples will clarify things out!


In Spock Framework you can run initialization for the whole Specification/class in setupSpec() method and do cleanup in cleanupSpec(). The methods have to be named in this way.

Here’s an example:

package com.farenda.solved

import spock.lang.Shared
import spock.lang.Specification

class BeforeAfterSpecTest extends Specification {

    // Must be @Shared or static!
    def @Shared VeryCostlyObject heavy

    // Run before all the tests:
    def setupSpec() {
        println("Heavy init for all the tests...")
        heavy = new VeryCostlyObject()
        println("Initialization done!")

    // Run after all the tests, even after failures:
    def cleanupSpec() {
        println("Cleanup after all tests!")

    def 'should create a range of 5 elements'() {
        println('Inside the range test.')
        (1..5).size() == 5

    def 'should miscount items in list'() {
        println('(mis)counting items in a list test')
        [1, 2, 3].size() == 4 // lets fail this one!

Beware that setupSpec() and cleanupSpec() can operate only on static and @Shared fields, because they are executed before tests get even instantiated. You can think of them as static methods on Specification, so they work outside an instance, similarly to JUnit‘s @BeforeClass and @AfterClass annotation.

If you try to assign to non-shared or non-static field you will get an error Only @Shared and static fields may be accessed from here!

Running the test gives the following output:

Heavy init for all the tests...
Instantiating very costly object...
...5 minutes later ;-)
Initialization done!
Inside the range test.
(mis)counting items in a list test

Condition not satisfied:

[1, 2, 3].size() == 4 // lets fail this one!
          |      |
          3      false
 <Click to see difference>

      at com.farenda.solved.BeforeAfterSpecTest.should count items in list(BeforeAfterSpecTest.groovy:32)

Cleanup after all tests!

Process finished with exit code 255

As you can see setupSpec() and cleanupSpec() have been called only once for all the tests. The thing to note is that cleanupSpec() has been called even when the test failed, allowing us to dispose resources.

Have fun! :-)

Share with the World!