Java Programming Tutorials

Java programming tutorials with many code examples!

AutoCleanup Spock test resources

Problem:

How to AutoCleanup Spock test resources? It turns out that Spock Framework has a flexible mechanism just for that purpose. Let’s write some code to test it!

Solution:

The following simple Java class will serve as a mannequin for tests of Spock’s @AutoCleanup feature:

package com.farenda.spock;

public class VeryCostlyObject {

    public VeryCostlyObject() {
        System.out.println("Instantiating very costly object...");
        System.out.println("...5 minutes later ;-)");
        System.out.println("Done!");
    }

    public void close() {
        System.out.println("Close method called!");
    }

    public void dispose() {
        System.out.println("Dispose method called!");
    }

    public void exceptional() {
        System.out.println("Exceptional method called!");
        throw new RuntimeException("Cannot close the resource.");
    }

    public void anotherExceptional() {
        System.out.println("Another exceptional method called!");
        throw new RuntimeException("Cannot close the resource.");
    }
}

As you can see the class has a couple of methods that all serve for releasing resources. In the test below we’re going to show how to call that methods in a different ways:

package com.farenda.spock

import spock.lang.AutoCleanup
import spock.lang.Specification

class AutoCleanupTest extends Specification {

    @AutoCleanup
    def resource = new VeryCostlyObject()

    @AutoCleanup('dispose')
    def anotherResource = new VeryCostlyObject()

    @AutoCleanup('exceptional')
    def faultyResource = new VeryCostlyObject()

    @AutoCleanup(value = 'anotherExceptional', quiet = true)
    def quiteResource = new VeryCostlyObject()

    def 'should close the resource'() {
        println 'Executing test'
        expect:
        Math.abs(-3) == 3
    }
}

The @AutoCleanup annotation works as follows:

  • by default it calls close() method,
  • cleanup method name can be passed as the single parameter or value when more attributes are used,
  • exceptions from executed method are reported by default, as can be seen at the end of the output below,
  • use quiet = true to silent exceptions from the method,
  • if more that one object is annotated with @AutoCleanup then closing is performed in reverse order of declaration,
  • cleanup of @Shared objects is performed after all tests (just like cleanupSpec()).

Let’s see how the above test is executed:

Instantiating very costly object...
...5 minutes later ;-)
Done!
Instantiating very costly object...
...5 minutes later ;-)
Done!
Instantiating very costly object...
...5 minutes later ;-)
Done!
Instantiating very costly object...
...5 minutes later ;-)
Done!
Executing test
Another exceptional method called!
Exceptional method called!
Dispose method called!
Close method called!

java.lang.RuntimeException: Cannot close the resource.

      at com.farenda.spock.VeryCostlyObject.exceptional(VeryCostlyObject.java:21)
      at org.spockframework.runtime.extension.builtin.AutoCleanupInterceptor.intercept(AutoCleanupInterceptor.java:58)
      at org.spockframework.runtime.extension.MethodInvocation.proceed(MethodInvocation.java:87)
      at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
      at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:117)
      at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:234)
      at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:74)
      at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)

Nice and useful feature. :-)

Share with the World!