Java Programming Tutorials

Java programming tutorials with many code examples!

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!
  • Joao Vitor Marques

    and if i modify the heavy object in the “should create a range…” test? Does the “should miscount…” test get the modified heavy object or the original one?

    • Modified. Think about @Shared object as an object assigned to a static field – all other objects see the same thing.