2017-08-26 55 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 
     } 
    } 
}