Programming for fun and profit

Programming tutorials, problems, solutions. Always with code.

Spock Framework expect with where block


How to write data-driven tests using Spock’s expect with where block? Where blocks are power feature of Spock Framework!


One reason to use Spock for testing? Powerful where block that allows to express relations between values in test or, in other words, perform parametrized tests:

package com.farenda.spock

import spock.lang.Specification

class SpockExpectWhereTest extends Specification {

    def 'should select max of two numbers'() {
        Math.max(a, b) == c

        a | b | c // these are vars will be available above in test,
        5 | 1 | 5 // initialized to these values!
        9 | 9 | 9

expect is basically the same as then in given-when-then, but doesn’t require *when part, hence is shorter. given may be, well, given to *initialize some values, but is not required.

Spock executes as many tests as there are rows in the where block. So, in this case, two tests with the values of a, b, and c respectively:

  • the first test: 5, 1, 5
  • the second test: 9, 9, 9.

The where block can be formatted horizontally as data pipes, which is sometimes more convenient:

a << [5, 9]
b << [1, 9]
c << [5, 9]

The result is the same, but the data is provided by… data provider, which can be Collections, Strings, Iterables, or fetch data from external sources, like so:

def sql = Sql.newInstance("jdbc:h2:mem:", "org.h2.Driver")
[a, b, c] << sql.rows("select a, b, c from mytable")
// or even:
// [a, b, _, c] << sql.rows("select * from mytable")

Fantastic feature! It makes tests so simple and readable! :-)

Share with the World!