'Difference between 'setup' and 'setupSpec' when initialising a Spock stub?

I am confused about stub initialize in setup() and setupSpec(), demo:

class SpockTestSpec extends Specification {
    @Shared Service service
    @Shared MsgClient msgClient
    @Shared QueryResult queryResult

    def setupSpec() {
        msgClient = Stub(MsgClient)
        queryResult = Stub(QueryResult)
        service = new Service(msgClient: msgClient)
    }

    def "test1"() {
        given:
        def msg = "hello world"
        def queryId = "abc123"

        queryResult.getQueryId() >> queryId
        msgClient.submitAsync(_) >> queryResult

        when:
        def resp = service.query(msg)

        then:
        resp.getMsg() == msg
        resp.getQueryId() == queryId
    }
}

It cannot work because the stub queryResult return "", which expect a queryId. when I use a setup() it works well:

class SpockTestSpec extends Specification {
    @Shared Service service
    @Shared MsgClient msgClient
    @Shared QueryResult queryResult

    def setup() {
        msgClient = Stub(MsgClient)
        queryResult = Stub(QueryResult)
        service = new Service(msgClient: msgClient)
    }

    def "test1"() {
        given:
        def msg = "hello world"
        def queryId = "abc123"

        queryResult.getQueryId() >> queryId
        msgClient.submitAsync(_) >> queryResult

        when:
        def resp = service.query(msg)

        then:
        resp.getMsg() == msg
        resp.getQueryId() == queryId
    }
}

What is the difference between init stub in setup() and setupSpec()?



Solution 1:[1]

It is a current limitation of Spock that you can't create usable @Shared mocks. Mocks are cheap to create so there is no reason to share them. It would introduce needless coupling between tests. As stated in this issue there is a workaround, but I strongly advise against it.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Leonard Brünings