What's good style for preconditions in Spock feature methods?
Asked Answered
P

2

8

In a feature method, one specifies the feature action in a when: block, the result of which gets tested in a subsequent then: block. Often preparation is needed, which is done in a given: clause (or setup: or fixture method). It is equally useful to include preconditions: these are conditions which are not the subject of the feature test (thus should not be in a when:-then: or expect:) but they assert/document necessary conditions for the test to be meaningful. See for example the dummy spec below:

import spock.lang.*

class DummySpec extends Specification {
  def "The leading three-caracter substring can be extracted from a string"() {
    given: "A string which is at least three characters long"
    def testString = "Hello, World"

    assert testString.size() > 2

    when: "Applying the appropriate [0..2] operation"
    def result = testString[0..2]

    then: "The result is three characters long"
    result.size() == 3
  }
}

What is the suggested practice for these preconditions? I used assert in the example but many frown upon asserts in a Spec.

Plum answered 13/11, 2014 at 9:31 Comment(1)
This is what I'd do. There's nothing wrong with using assert in a spec when needed (it's still a Spock condition, not a Groovy assertion).Glynis
H
7

I've been always using expect for such scenarios:

@Grab('org.spockframework:spock-core:0.7-groovy-2.0')
@Grab('cglib:cglib-nodep:3.1')

import spock.lang.*

class DummySpec extends Specification {
  def "The leading three-caracter substring can be extracted from a string"() {
    given: "A string which is at least three characters long"
    def testString = "Hello, World"

    expect: "Input should have at least 3 characters"
    testString.size() > 3

    when: "Applying the appropriate [0..2] operation"
    def result = testString[0..2]

    then: "The result is three characters long"
    result.size() == 3
  }
}
Hyp answered 13/11, 2014 at 9:50 Comment(1)
thanks for your answer, @opal, I myself actually prefer assert to expect and am following @peter-niederwieser's advice.Contractive
I
0

Although I don't believe that this is suggested practice, another alternative that helps retain the English-language readability of the code is using the descriptive and: clause provided by Spock.

def "The leading three-character substring can be extracted from a string"() {
    given: "A test string"
    def testString = "Hello, World"

    and: "the input should have at least 3 characters"
    testString.size() > 3

    when: "Applying the appropriate [0..2] operation"
    def result = testString[0..2]

    then: "The result is three characters long"
    result.size() == 3
}

Since and: doesn't have any special meaning when Spock compiles your test method, you can use it as much as you like and wherever you would like within the test method.

Issiah answered 11/9, 2018 at 20:26 Comment(1)
The test will not fail in this case if testString has less than three characters. The intent is to enforce the preconditions.Conductor

© 2022 - 2024 — McMap. All rights reserved.