I was trying to setup a common array of objects which are loaded and deserialised from json file in resources and tried to do this by using groovy trait with setup() method.
Trait:
Object[] arr
@BeforeClass
def setupTrait() {
arr = loadFromFile("xxx.json")
}
Test:
def setup() {}
def "test"() {
arr.size() //here arr is null, although the setup in groovy is called
}
Working solution.
Trait:
static Object[] arr = loadFromFile("xxx.json")
Test:
def setup() {}
def "test"() {
arr.size() //here arr is ok.
}
The question is why the first isn't working right? If I use @Before annotation and arr is loaded before each test, it's somehow working...
There are some minor mistakes that I suggest to rewrite in a more "spock"-y way:
def setupSpec()
fixture method and not @BeforeClass
setupSpec
that indeed will run only once for all test cases you are supposed to put @Shared
annotation on the field.But then, even if the code will look like this:
trait SampleTrait {
@Shared List arr
def setupSpec() {
arr = [1,2,3]
}
}
It still doesn't work. Now, It looks like you've encountered an open issue in spock:
https://github.com/spockframework/spock/issues/83
The issue is open, but the workaround exists and is suggested in the discussion: put a word static (you have actually done that :)). The reason: @Shared
annotation cannot be processed by Spock when they appear in traits.
So, all-in-all I believe the best you can get is:
trait SampleTrait {
static List arr
def setupSpec() {
arr = [1,2,3]
}
}
class SampleTestSpec extends Specification implements SampleTrait {
def "list equality"() {
expect:
arr == [1,2,3]
}
}