我应该如何在Spek中设置可变测试夹具?

我正试图在斯佩克的灯光中find我的头。 文档中的计算器示例很容易遵循,但是我不确定如何在构建安装/拆卸时执行某些固定设备。 例如,如果我正在测试一个列表:

describe("a list") { val list = arrayListOf() // Only instantiated once on("adding an item") { list.add(123) it("has a size of one") { list.size.should.equal(1) } } on("adding 2 items") { list.add(1) list.add(2) it("has a size of 2") { list.size.should.equal(2) // Fails, 3 != 2 } } } 

据我所知,在Spek中, describe块只被评估一次,所以只有一个List实例。 该文档有助于建议使用测试装置,但无助于举一个例子!

我认为以下方法是行不通的,因为Kotlin不了解Spek之前一定会on beforeEachTest之前调用

 describe("a list") { var list : MutableList beforeEachTest { list = arrayListOf() } on("adding an item") { list.add(123) // Compile error, list must be initialised 

我可以通过使variables为空来解决这个问题,但是我必须在任何地方使用nullsafe操作符,这很糟糕,因为我知道它不是空的:

 describe("a list") { var list : MutableList? = null beforeEachTest { list = arrayListOf() } on("adding an item") { list?.add(123) // Bleh 

这也适用,但意味着每一个设置代码现在需要在两个地方复制

 describe("a list") { var list = arrayListOf() beforeEachTest { list = arrayListOf() // Bleh } on("adding an item") { list.add(123) 

对不起,如果有任何明显的,但我来自JUnit的世界,每一个测试之前,一切(酒吧静态)被拆除和重建,所以这一切都显得相当陌生!

如果你使用Kotlin 1.1和Spek 1.1.0你可以使用memoized

 describe("a list") { val list by memoized { arrayListOf() } on("adding an item") { list.add(123) it("has a size of one") { list.size.should.equal(1) } } on("adding 2 items") { list.add(1) list.add(2) it("has a size of 2") { list.size.should.equal(2) } } } 

每一个都将有一个独特的list实例。 您可以传递一个CachingModememoized以控制Spek如何缓存这些值。

  • CachingMode.TEST (默认) – 每个测试将有一个唯一的实例( on这里是一个特殊的情况,并作为一个test对待)
  • CachingMode.SCOPE – 将有一个唯一的实例,实际上是一个单例。
  • CachingMode.GROUP – 每个group都将有一个唯一的实例。

memoized仍然是可用的前Kotlin 1.1和至少Spek 1.1.0-beta3 ,但语法有点笨重。

 describe("a list") { val list = memoized { arrayListOf() } on("adding an item") { list().add(123) it("has a size of one") { list().size.should.equal(1) } } on("adding 2 items") { list().add(1) list().add(2) it("has a size of 2") { list().size.should.equal(2) } } }