Spock label combinations
Asked Answered
M

1

14

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.

Manes answered 10/10, 2015 at 0:59 Comment(0)
A
21

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 surprise 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 stating 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 actually split into two separate tests.

I hope this answered at least some of your questions.

Alain answered 10/10, 2015 at 15:1 Comment(6)
Thanks @Alain (+1) - if you could explain the where label a little bit more I think I should be all set!Manes
Hi @smeeb, I will try to edit my response when I have more time. In the meantime you could have a look at tests I have created some time ago in Spock. There are plenty of parametrized tests over there (the ones with where label). Hopefully it will give you better insight of what they are capable of and how useful they can be. tests are available hereAlain
Not that I would be a fan of the approach (at least not without proper documentation), but combining when/then and expect within one test could be useful to manipulate Stub/Mock scoping to override methods differently between then when/then & expect blocks.Trucking
It's not nearly complete, but I've started to document everything I've been learning about Spock. Here are some examples of the where labelTrucking
@Alain Is given an alias for setup? I wanted to use setup before a given and was rejectedZalea
@FedericoPiazza yes, it is. Hence one would either use a setup or given but not both at the same time, the additional grouping can be achieved through and label.Alain

© 2022 - 2024 — McMap. All rights reserved.