Spock's unroll feature is very powerful. The provider data variables can be used in the method description of our specification features with placeholders. For each iteration the placeholders are replaced with correct values. This way we get a nice output where we immediately can see the values that were used to run the code. Placeholders are denoted by a hash sign (#
) followed by the variable name. We can even invoke no-argument methods on the variable values or access properties. For example if we have a String value we could get the upper case value with #variableName.toUpperCase()
. If we want to use more complex expressions we must introduce a new data variable in the where
block. The value of the variable will be determined for each test invocation and we can use the result as a value in the method description.
package com.mrhaki.spock import spock.lang.* class SampleSpec extends Specification { @Unroll def "check if '#value' is lower case"() { expect: value.every { (it as char).isLowerCase() } == result where: value || result 'A' || false 'Ab' || false 'aB' || false 'a' || true 'ab' || true } }
If we look at the output of the tests we see the method names are not really representing the code we test. For example we can not see if the value was lower case or not.
We rewrite the specification and add a new data variable unrollDescription
in the where
block. We then refer to this variable in our method name description.
package com.mrhaki.spock import spock.lang.* class SampleSpec extends Specification { @Unroll // Alternatively syntax as // unroll annotation argument: // @Unroll("'#value' is #unrollDescription") def "'#value' is #unrollDescription"() { expect: value.every { (it as char).isLowerCase() } == result where: value || result 'A' || false 'Ab' || false 'aB' || false 'a' || true 'ab' || true unrollDescription = result ? 'lower case' : 'not lower case' } }
When we look at the output we now have more descriptive method names:
This post is inspired by the great Idiomatic Spock talk by Rob Fletcher at Gr8Conf 2014 Europe.
Code written with Spock 0.7 for Groovy 2.