【问题标题】:How should I set up mutable test fixtures in Spek?我应该如何在 Spek 中设置可变测试装置?
【发布时间】:2017-03-26 17:05:31
【问题描述】:

我正在努力了解 Spek 的固定装置。 The Calculator example in the docs 很容易理解,但是当某些固定装置是有状态的时,我不确定如何进行结构化设置/拆卸。例如,如果我正在测试一个列表:

describe("a list") {
    val list = arrayListOf<Int>() // 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<Int>

    beforeEachTest {
        list = arrayListOf()
    }

    on("adding an item") {
        list.add(123) // Compile error, list must be initialised

我可以通过使变量为空来解决这个问题,但是我必须在任何地方都使用空安全运算符,这很糟糕,因为我知道它永远不会为空:

describe("a list") {
    var list : MutableList<Int>? = null

    beforeEachTest {
        list = arrayListOf()
    }

    on("adding an item") {
        list?.add(123) // Bleh

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

describe("a list") {
    var list = arrayListOf<Int>()

    beforeEachTest {
        list = arrayListOf() // Bleh
    }

    on("adding an item") {
        list.add(123)

如果有任何明显的问题,请原谅,但我来自 JUnit 世界,在每次测试之前绝对所有东西(条形静态)都被拆除并重建,所以这一切看起来都很陌生!

【问题讨论】:

    标签: testing kotlin fixtures


    【解决方案1】:

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

    describe("a list") {
        val list by memoized { arrayListOf<Int>() }
    
        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)
            }
        }
    }
    

    每个on 都会有一个唯一的list 实例。您可以将CachingMode 传递给memoized 来控制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<Int>() }
    
        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)
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-23
      • 2018-02-21
      相关资源
      最近更新 更多