Kotlintest拦截器和lateinit vars

时间:2017-08-26 14:25:26

标签: testing kotlin

我有一些共享设置的测试用例。它们都需要两个可以以相同方式初始化的字段。所以我认为我可以将它们提取到lateinit var字段中并在测试用例拦截器中创建它们。
但是当我尝试在我的测试用例中访问它们时,它们总是会抛出异常,因为它们没有被初始化。
有没有办法在每个测试用例之前创建字段?

到目前为止,这是我的代码:

class ElasticsearchFieldImplTest : WordSpec() {

    // These 2 are needed for every test
    lateinit var mockDocument: ElasticsearchDocument
    lateinit var mockProperty: KProperty<*>

    override fun interceptTestCase(context: TestCaseContext, test: () -> Unit) {
        // Before Each
        mockDocument = mock()
        mockProperty = mock {
            on {name} doReturn Gen.string().generate()
        }

        // Execute Test
        test()

        // After Each
    }

    init {
        "ElasticsearchFields" should {
            "behave like normal var properties" {
                val target = ElasticsearchFieldImpl<Any>()
                // Here the exception is thrown
                target.getValue(mockDocument, mockProperty) shouldBe null

                val testValue = Gen.string().generate()
                target.setValue(mockDocument, mockProperty, testValue)
                target.getValue(mockDocument, mockProperty) shouldBe testValue
            }
        }
    }
}

当我使用调试器逐步执行它并在interceptTestCase方法中设置断点时,我看到它在测试之前执行并且属性已初始化。然后我前进到测试,在其中属性不再被初始化。

2 个答案:

答案 0 :(得分:1)

КлаусШварц的回答不正确。这不是kotlintest的工作原理 - init lambdas中的仅创建,而不是运行。因此您无法访问lateinit var块中的init。他们从未分配任何价值。

这不起作用,因为kotlintest中的错误,在这里描述(实际上几乎已经解决):https://github.com/kotlintest/kotlintest/issues/174

简而言之 - 在不同的实例上调用interceptTestCase而不是实际测试。所以它根本不影响你的测试。

解决方法是覆盖属性: override val oneInstancePerTest = false

然后只有一个实例且interceptTestCase正常工作,但您必须记住 - 所有测试只有一个实例

Kotlintest 3.0将免于此错误。 (但默认情况下,所有测试可能都有一个实例。)

答案 1 :(得分:0)

在初始化之前,您不应该访问lateinit vars

问题是您正在访问lateinit varinit {}内的interceptTestCase()块,这是默认构造函数,它在mockDocument之前被调用。

这里最简单的方法就是让mockPropertyvar mockDocument: ElasticsearchDocument? = null var mockProperty: KProperty<*>? = null 可以为空。

!!

如果您希望测试崩溃,如果这些字段未初始化,则添加init { "ElasticsearchFields" should { "behave like normal var properties" { val target = ElasticsearchFieldImpl<Any>() // Here the exception is thrown target.getValue(mockDocument!!, mockProperty!!) shouldBe null val testValue = Gen.string().generate() target.setValue(mockDocument!!, mockProperty!!, testValue) target.getValue(mockDocument!!, mockProperty!!) shouldBe testValue } } } 修饰符:

getValue(e) {
    console.log(JSON.parse(e.target.value));
  }

  render() {

  let cc = [{
    value: '1st',
    id: 1
  },
  {
   value: '2nd',
    id: 2
  }]
  
  <select onChange={e => this.getValue(e)}>
          <option value={JSON.stringify(cc[0])}>One</option>
          <option value={JSON.stringify(cc[1])}>Two</option>
</select>
}