Spock Framework Documentation

repository·master·Indexed 25 days ago

https://github.com/spockframework/spock

A BDD-style testing and specification framework for Java and Groovy. This documentation covers development environment setup for JDK 11 and 17, IDE configuration for IntelliJ IDEA and Eclipse, and detailed guides on data-driven testing using data tables, pipes, and the combined: label. It also details framework extensions such as @Ignore, @Requires, @Stepwise, and @PendingFeature, as well as global configuration via SpockConfig.groovy.

Tokens
13.9K
Snippets
32
Records
104
Agent score
86%

What's inside Spock

  1. Overview of Spock Framework

    master
    Spock is a BDD-style (Behavior-Driven Development) developer testing and specification framework designed for Java and Groovy applications. It is based on the JUnit Platform and requires Java 8+ and Groovy 2.5+. For projects using Java 12+, Groovy 3.0 or newer is recommended.
  2. Limitations of using Traits with Specifications

    master
    Traits on Specifications are not officially supported by Spock due to how Groovy implements traits and AST transformations. While some use cases may work, there is no guarantee that AST transformations will run on a trait as they do on a regular class. Use traits in Specifications at your own risk.
  3. Set up the Spock development environment

    master

    Spock is built with Gradle. To develop locally, you must have both JDK 11 and JDK 17 installed. The build process itself runs on JDK 17, but requires JDK 11 to be available via Gradle toolchains.

    1. Clone the repository.
    2. Ensure JDK 11 and 17 are installed.
    3. If Gradle cannot find JDK 11, set the JDK11 environment variable to its location.
    4. Verify toolchains by running ./gradlew javaToolchains.
    5. Run the build using the Gradle Wrapper: ./gradlew build.
  4. Use JUnit 4 features in Spock 2.0

    master
    Support for JUnit 4 has been removed from the core spock-core module. If your codebase requires JUnit 4 features (such as @Rule), you must include the spock-junit4 module. Additionally, you should replace the JUnit 4 TemporaryFolder rule with the Spock built-in @TempDir extension.
  5. Install the Spock Spring module

    master

    To enable integration with the Spring TestContext Framework (including support for @ContextConfiguration, @ContextHierarchy, @BootstrapWith, @SpringBootTest, and @WebMvcTest), add the following dependency to your project:

    org.spockframework:spock-spring

    org.spockframework:spock-spring
  6. Create an annotation-driven local extension

    master

    To create a local extension driven by annotations, implement the IAnnotationDrivenExtension interface.

    Requirements for your annotation class:

    1. Must have @Retention(RUNTIME).
    2. Must have @Target set to FIELD, METHOD, or TYPE (depending on usage).
    3. Must be annotated with @ExtensionAnnotation(YourExtensionClass.class).

    Note on Spock 2.4+: If your extension is thread-safe and does not need to store Specification-specific state, implement IStatelessAnnotationDrivenExtension instead.

    Repeatable Annotations: Since Spock 2.0, annotations can be @Repeatable. Use the visit...Annotations(List<T> annotations, ...) methods to handle multiple instances applied to the same target.

  7. Inject Method Parameters (Spock 2.4+)

    master

    Since Spock 2.4, extensions can target method parameters directly.

    1. Define an annotation with @Target({ElementType.PARAMETER}).
    2. Implement IAnnotationDrivenExtension.visitParameterAnnotation(T annotation, ParameterInfo parameter).
    3. Register a custom interceptor or use the built-in ParameterResolver.Interceptor to handle the injection.

    Manual Injection (Pre-2.4 or Advanced): You can manually inject values by modifying invocation.arguments. For Spock 2.0+, the arguments array size matches the method parameter count. If you need to expand it, you must create a new array, copy existing elements, and assign the new array to invocation.arguments.

  8. Run a Spock Example Project locally

    master
    To run Spock in your local development environment, use the Spock Example Project. The project includes pre-configured builds for Ant, Gradle, and Maven that require no additional setup. The Gradle build is designed to bootstrap Gradle itself and can be used to set up environments in Eclipse or IntelliJ IDEA with a single command.
  9. Fix Class Initialization Order issues (Spock 0.6+)

    master

    In Spock 0.6 and later, the initialization order for inherited specifications changed to a more conventional order: field initializers are executed by class level (Base fields, then Derived fields) before any setup() methods are called.

    This means you cannot rely on a base class setup() method to initialize a field that a derived class uses in its field initializer.

    Broken Pattern:

    class Base extends Specification {
        def base
    
        def setup() { base = "base" }
    }
    
    class Derived extends Base {
        def derived = base + "derived" // base is not yet set
    }

    Solutions:

    1. Use a field initializer for base in the Base class.
    2. Move the assignment of derived into a setup() method in the Derived class.
  10. Use Global Groovy Mocks to replace all instances

    master

    A global Groovy mock (GroovyMock(global: true)) automatically replaces all real instances of a specific class type for the duration of the feature method. This is useful for intercepting objects that are not explicitly injected.

    Cautions:

    • Constructor Replacement: GroovyMock(global: true) replaces constructor calls, which return null by default. Use GroovySpy(global: true) if you want to keep real constructors working.
    • JDK Types: Avoid using global mocks for standard JDK types like ArrayList.
    • Declaration Order: The global mock must be declared before any new instances of that type are created in the code under test.
    • Parallel Execution: If using parallel execution, global mocks require the spec to be annotated with @Isolated or the feature to be annotated with @ResourceLock(org.spockframework.runtime.model.parallel.Resources.META_CLASS_REGISTRY).