Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spock label combinations

Tags:

groovy

spock

There | are | so many | Spock | spec examples of how to use its labels, such as:

// when -> then label combo
def "test something"() {
    when:
    // blah

    then:
    // blah blah
}

Such label combinations as:

  • when -> then
  • given -> when -> then
  • expect
  • given -> expect

But nowhere can I find documentation on what the legal/meaningful combinations of these labels are. For instance, could I have:

def "do something"() {
    when:
    // blah

    expect:
    // blah
}

Could I? I do not know. What about:

def "do something else"() {
    when:
    // blah

    then:
    // blah

    expect:
    // blah

    where:
    // blah
}

Could I? Again, I do not know. But I wonder.

like image 278
smeeb Avatar asked Oct 10 '15 00:10

smeeb


1 Answers

I am actually an author of one of the tutorials you have mentioned. I think the best to answer your question would be to really understand what particular labels are for. Maybe then it would be more obvious why certain combinations make sense and other do not. Please refer to original documentation http://spockframework.github.io/spock/docs/1.0/spock_primer.html. It explains really well all labels and their purpose. Also it comes with this diagram:

Spock labels

Which I hope should already tell you a lot. So for instance having both when and expect labels makes not much sense. The expect label was designed to substitute both when and then. The reasoning behind it is well explained in the documentation:

An expect block [...] is useful in situations where it is more natural to describe stimulus and expected response in a single expression.

Spock itself will not allow you to use this combination. If you try to execute following code.

def "test"() {
    when:
        println("test")

    expect:
        1==1
}

You will receive an error message like this.

startup failed: /Users/wooki/IdeaProjects/mylibrary/src/test/groovy/ExampleTest.groovy: 13: 'expect' is not allowed here; instead, use one of: [and, then] @ line 13, column 9.

To my suprise the second of your examples works. However I believe there is really not much gain of using expect here instead of and as I would normally do.

def "do something else"() {
    when:
    // stimulus

    then:
    // 1st verification

    and:
    // 2nd verification

    where:
    // parametrization
}

The only reason to have expect or and after then is to separate code responsible for verifying the result of executing the code inside when label. For instance to group verifications that are somehow related to each other, or even to separate single verifications but to have a possibility of giving them a description using strings that can be attached to labels in Spock.

def "do something else"() {
    when:
    // stimulus

    then: "1 is always 1"
       1 == 1

    and: "2 is always 2"
       2 == 2
}

Hence, since you are already stateing that verification part of the test began (using then block) I would stick to and label for separating further code.

Regarding where label. It works sort of as a loop indicator. So whatever combinations of labels you use before you could always put at the end the where label. This one is not really a part of a single test run, it just enforces the test to be run a number of times.

As well it is possible to have something like this:

def "test"() {
    given:
        def value

    when:
        value = 1

    then:
        value == 1

    when:
        value = 2

    then:
        value == 2
}

Using the above, just make sure that your test is not "testing too much". Meaning that maybe a reason why you use two groups of when-then makes a perfect excuse for this test to be acutally splitted into two separate tests.

I hope this answered at least some of your questions.

like image 154
wooki Avatar answered Oct 09 '22 21:10

wooki