Over a million developers have joined DZone.

Introducing Spock, a testing and specification framework for the JVM

DZone 's Guide to

Introducing Spock, a testing and specification framework for the JVM

· Java Zone ·
Free Resource

Spock is a new testing and specification framework for Java and Groovy developers. When spreading the word about Spock, I often get the question: "Why on earth would I need yet another testing framework? Aren't there enough xUnit/xSpec clones out there already?" In this post, I'll try to show you how Spock is different, and why it is worth a closer look.


Assertions are the most fundamental way to express how a piece of software should behave. It's almost a tradition that every new testing framework comes with its own assertion API, adding a few wrinkles here and there, and naming things a little differently. For example, to say that two things are equal, you would typically write something like:

  • assertEquals(x, y)
  • x.shouldEqual(y)
  • x.mustBe(y)

Every now and then, a stranger comes along and asks if he can't just use plain boolean expressions instead of an assertion API. But we all know that boolean expressions can't tell us why they failed. Or can they? Meet Spock!

class Assertions {
def "comparing x and y"() {
def x = 1
def y = 2

x < y // OK
x == y // BOOM!

In Spock, assertions come after the expect: label, and are just what the stranger asked for - plain boolean expressions! Here is what we get when we run this test:

Condition not satisfied:

x == y
| |  |
1 |  2

Of course this doesn't just work for simple comparisons, but for arbitrary assertions. Here is another, slightly more interesting output:

Condition not satisfied:

Math.max(a, b) > c
|   |  |  | |
112 |  94 | 115
112   false

Again, Spock's runtime has collected all relevant information, and presents it in an intuitive way. Nice, isn't it?

Data-driven tests

Although data-driven testing is a natural extension of state-based testing, it doesn't seem to be used very often. I suppose this is because test frameworks make writing data-driven tests rather hard. All of them? Meet Spock!

class DataDriven {
def "maximum of two numbers"() {
Math.max(a, b) == c

a << [7, 4, 9]
b << [3, 5, 9]
c << [7, 5, 9]

The expect block provides just the test logic, using the free (i.e. undefined) variables a, b and c as placeholders for data. It's then up to the where block to bind concrete values to these variables. When this test is run, it is repeated three times: first with a = 7, b = 3, and c = 7; then with a = 4, b = 5, and c = 5; and finally with a = b = c = 9.

Of course, the test data doesn't have to be baked into the test. For example, let's try to load it from a database instead:


class DataDriven {
@Shared sql = Sql.newInstance("jdbc:derby:spockdata", "org.apache.derby.jdbc.EmbeddedDriver")

def "maximum of two numbers"() {
Math.max(a, b) == c

row << sql.rows("select * from maxdata")
a = row["a"]
b = row["b"]
c = row["c"]

Here the values for a, b, and c are taken from the equally named columns of the maxdata table, until no more rows are left. Using a syntax similar to Groovy's multi-assignment, the where block can be simplified even further:

[a, b, c] << sql.rows("select a, b, c from maxdata")

Together with the creation of the Sql instance above, we are now down to two lines of code to load our test data from a database. How easy is that?


Assertions and data-driven tests are just two areas where Spock achieves more with less. At http://spockframework.org, you will also meet Spock's incredibly lean mocking framework, its interception-based extension mechanism, and other fascinating life forms. If you have any questions or suggestions, please write us at http://groups.google.com/group/spockframework, or file an issue at http://issues.spockframework.org. I'm looking forward to your feedback!

Peter Niederwieser
Founder, Spock Framework


Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}