Spock Framework Logo

Spock

the enterprise-ready specification framework

Spock is a testing, specification, and mocking framework for JVM developers that emphasizes readability and clarity. By blending BDD concepts and Groovy's concise syntax, Spock helps teams write tests that are easy to understand and enjoyable to maintain.

Ready to Improve Your Testing?

Spock Latest Version for Groovy 2.5 Spock Latest Version for Groovy 3.0 Spock Latest Version for Groovy 4.0 Spock Latest Version for Groovy 5.0

Why Choose Spock?

Expressive Specifications

Write tests that are easy to read and understand, even for non-programmers.

Powerful Mocking

Create flexible and powerful mocks and stubs with built-in support.

JUnit Platform

Seamless integration with JUnit 5+ and build tools.

Data-Driven Testing

Easily run the same test with different sets of data.

Groovy DSL

Leverage the power and flexibility of the Groovy language.

Built-in Matchers

Use a rich set of matchers to verify expectations with clarity.

See How Readable Tests Can Be

// CalculatorSpec.groovy
import spock.lang.Specification

class CalculatorSpec extends Specification {

    def "Test calculate method: #a #operation #b = #expectedResult"() {
        given: "A calculator instance"
        def calculator = new Calculator()

        expect: "The calculation should match the expected value"
        calculator.calculate(a, b, operation) == expectedResult

        where: "Define test data"
        a  | b  | operation || expectedResult
        1  | 2  | "+"       || 3
        5  | 3  | "-"       || 2
        4  | 2  | "*"       || 8
        10 | 2  | "/"       || 5
        -1 | 1  | "+"       || 0
        1  | -1 | "-"       || 2
        -2 | -2 | "*"       || 4
        -4 | -2 | "/"       || 2
        1  | 1  | "+"       || 42 // A failing test case
    }

    def "Test calculate method with division by zero"() {
        given: "A calculator instance"
        def calculator = new Calculator()

        when: "Perform division by zero"
        calculator.calculate(10, 0, "/")

        then: "An IllegalArgumentException is thrown"
        def exception = thrown(IllegalArgumentException)

        and: "The exception message is correct"
        exception.message == "Cannot divide by zero"
    }

    def "Test calculate method with invalid operation"() {
        given: "A calculator instance"
        def calculator = new Calculator()

        when: "Perform calculation with invalid operation"
        calculator.calculate(1, 2, "**")

        then: "An IllegalArgumentException is thrown"
        def exception = thrown(IllegalArgumentException)

        and: "The exception message is correct"
        exception.message == "Invalid operation: **"
    }
}


// Calculator.groovy
class Calculator {
    /**
     * Performs arithmetic operations on two integers.
     *
     * @param a         The first integer.
     * @param b         The second integer.
     * @param operation The operation to perform (+, -, *, /).
     * @return The result of the operation.
     * @throws IllegalArgumentException if the operation is invalid or division by zero is attempted.
     */
    int calculate(int a, int b, String operation) {
        switch (operation) {
            case "+": return a + b
            case "-": return a - b
            case "*": return a * b
            case "/":
                if (b == 0) {
                    throw new IllegalArgumentException("Cannot divide by zero")
                }
                return a / b
            default:
                throw new IllegalArgumentException("Invalid operation: " + operation)
        }
    }

    String toString() {
        return "Calc"
    }
}

Spock's clear given:, when:, then: blocks make understanding test logic intuitive.

Example Test Output:

╷
└─ Spock ✔
   └─ CalculatorSpec ✔
      ├─ Test calculate method: #a #operation #b = #expectedResult ✔
      │  ├─ Test calculate method: 1 + 2 = 3 ✔
      │  ├─ Test calculate method: 5 - 3 = 2 ✔
      │  ├─ Test calculate method: 4 * 2 = 8 ✔
      │  ├─ Test calculate method: 10 / 2 = 5 ✔
      │  ├─ Test calculate method: -1 + 1 = 0 ✔
      │  ├─ Test calculate method: 1 - -1 = 2 ✔
      │  ├─ Test calculate method: -2 * -2 = 4 ✔
      │  ├─ Test calculate method: -4 / -2 = 2 ✔
      │  └─ Test calculate method: 1 + 1 = 42 ✘ Condition not satisfied:
      │
      │           calculator.calculate(a, b, operation) == expectedResult
      │           |          |         |  |  |          |  |
      │           Calc       2         1  1  +          |  42
      │                                                 false
      ├─ Test calculate method with division by zero ✔
      └─ Test calculate method with invalid operation ✔
Try it online

Follow Us on