2017-08-26 26 views
2

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

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

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方法,我看到它在测试之前执行和属性初始化设置一个断点。然后我向前迈进测试,并在其中的属性不再初始化。

回答

1

КлаусШварц的答案是不正确。这不是如何kotlintest工作 - init lambda只是创建,不运行。因此,您不在init区块中访问您的lateinit var。他们从来没有分配任何价值。

这并不是因为kotlintest,描述(实际上几乎解决了)错误的在这里工作:https://github.com/kotlintest/kotlintest/issues/174

总之 - interceptTestCase叫做阶级比实际试验不同的实例。所以它对你的测试没有任何影响。

解决方法是重写属性: override val oneInstancePerTest = false

那么只有一个实例,interceptTestCase工作正常,但你要记住 - 只有一个所有测试实例。

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

0

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

问题是,您正在访问init {}块中的lateinit var块,该块是默认构造函数,它在interceptTestCase()之前调用。

这里最简单的方法就是让mockDocumentmockProperty为空。

var 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 
     } 
    } 
}