Introduction
Spock is a testing and specification framework for Java and Groovy that uses Groovy's expressive syntax to create readable, well-structured tests. Its BDD-style blocks (given/when/then/expect/where) and built-in data-driven testing via where-tables make it a popular choice for enterprise Java projects that want tests to serve as living documentation.
What Spock Does
- Structures tests using BDD blocks: given (setup), when (stimulus), then (assertions), expect (combined), and where (data tables)
- Provides built-in mocking, stubbing, and interaction-based testing without additional libraries
- Supports data-driven testing with where-blocks that iterate over tabular test data
- Integrates with Spring Boot for testing dependency-injected components and web endpoints
- Runs on the JUnit platform, making it compatible with existing build and CI tooling
Architecture Overview
Spock extends JUnit's test runner infrastructure through a custom Sputnik runner (JUnit 4) or SpockEngine (JUnit Platform). Specifications are Groovy classes that extend Specification. At compile time, Spock's AST transformations convert the BDD block structure into executable test methods. The mock framework intercepts method calls on mock objects at runtime and records interactions for verification in then-blocks. Extensions (annotations like @Timeout, @Retry, @SpringBean) hook into Spock's lifecycle to add cross-cutting behavior.
Self-Hosting & Configuration
- Add spock-core as a test dependency in Gradle or Maven, matching your Groovy version (groovy-4.0 for Groovy 4.x)
- For Spring Boot integration, add spock-spring and annotate specifications with @SpringBootTest
- Configure the Groovy compiler plugin in Maven or the Groovy plugin in Gradle to compile test sources
- Use @TempDir, @Timeout, and other built-in extensions via annotations on specification classes or methods
- Run Spock tests with standard Gradle (test task) or Maven (Surefire/Failsafe) commands; no special runner configuration needed
Key Features
- Expressive BDD blocks (given/when/then/expect/where) that make test intent clear to readers
- Data-driven testing with where-tables that generate a separate test iteration per row
- Built-in mocking and stubbing with interaction verification, eliminating the need for Mockito in most cases
- Spring Boot integration for testing controllers, services, and repositories with @SpringBean for mock injection
- Extension annotations (@Retry, @Timeout, @Stepwise, @Unroll) for common enterprise testing patterns
Comparison with Similar Tools
- JUnit 5 — the standard Java test framework; more verbose but does not require Groovy
- Mockito — dedicated mocking library for Java; Spock includes equivalent functionality built in
- TestNG — alternative Java test framework with data providers and parallel execution; XML-driven configuration
- Kotest — Kotlin testing framework with similar BDD style; better suited for Kotlin-only projects
- Cucumber — BDD framework using Gherkin feature files; separates specification from code, useful for non-developer stakeholders
FAQ
Q: Do I need to know Groovy to use Spock? A: Basic Groovy knowledge helps, but Spock tests look very close to pseudocode. Most Java developers can read and write Spock specifications after a short introduction to Groovy's syntax differences.
Q: Can Spock test Java code, not just Groovy? A: Yes. Spock is commonly used to test Java production code. The test specifications are written in Groovy, but the code under test is standard Java.
Q: How does Spock's mocking compare to Mockito? A: Spock mocks are declared inline and interactions are verified in then-blocks. Mockito uses verify() calls after the fact. Spock's approach is more concise for most cases, but Mockito offers some advanced features like argument captors.
Q: Does Spock work with JUnit 5? A: Yes. Spock 2.x runs on the JUnit Platform (JUnit 5 launcher) and can coexist with JUnit 5 tests in the same project.