spock icon indicating copy to clipboard operation
spock copied to clipboard

Allow "given" after "then" and "where"

Open NickGotv opened this issue 7 months ago • 3 comments

Describe the solution you'd like

we allow "when" after "then", so it makes sense to add "given" when I want to introduce new data when it's relevant, in case of a big multistep test

Describe alternatives you've considered

No response

Additional context

No response

NickGotv avatar May 30 '25 13:05 NickGotv

I'm not sure whether we really should allow that. If it is a "given", then you should be able to specify it in the upper-most given block. If it cannot be specified there, as it depends on things already done in the test, it is not really a "given", so it should be fine to just define it in the next when.

If you have such big multi-step tests, it might also worth considering whether the tests should be refactored maybe. 🤷‍♂️

Another option would be to use a @Stepwise specification where the features run in sequence and so could build on each other, each having its own given block. While that implies the same tendency for a need to refactor the test eventually, at least if we are talking about unit tests. :-)

Vampire avatar May 30 '25 14:05 Vampire

Case that arose this for me is a integration test. It couldn't be split into a @Stepwise, because it required to reproduce a multi-step operation, where previous results vere used as inputs in the next. And for readabilty it might be beneficial to be able to introduce variables when they are relevant, and be able to include them into "given" block to not confuse Example of how it has to be now:

given: "values for all tests below"
def a = ... // Something relevant for test 1
def b = ... // Something that is relevant only for test 2
when: "test 1"
def test1Res = subject.doStuff(a)

then:
....

when: "test 2, dependant on 1"
def test2Res = subject.doOtherStuff(test1Res, b)

then:
....

Alternative:

given: "values for test 1"
def a = ... 

when: "test 1"
def test1Res = subject.doStuff(a)

then:
....

given: "Additional values for test 2"
def b = ...

when: "test 2, dependant on 1"
def test2Res = subject.doOtherStuff(test1Res, b)

then:
....

NickGotv avatar May 30 '25 15:05 NickGotv

Or the other alternative:

given: "values for all tests below"
def a = ... // Something relevant for test 1
when: "test 1"
def test1Res = subject.doStuff(a)

then:
....

when: "test 2, dependant on 1"
def b = ... // Something that is relevant only for test 2
def test2Res = subject.doOtherStuff(test1Res, b)

then:
....

Besidest that, you say it cannot be made a stepwise spec, but why? Just define test1Res as a @Shared field, then you can assign to it in the first feature and use it in the second feature.

Vampire avatar May 30 '25 17:05 Vampire

Closing as a duplicate. Although the other issue is newer, it has a better description.

leonard84 avatar Aug 24 '25 13:08 leonard84