У меня есть несколько тестовых тегов, которые имеют общую настройку. Все они нуждаются в двух полях, которые могут быть инициализированы одинаково. Поэтому я думал, что могу извлечь их в полях 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
я вижу, что он выполняется перед тестом и что свойства инициализируются. Затем я перехожу к тесту, и в нем свойства уже не инициализируются.
Ответ Клауса Шварц неверен. Это не то, как работает kotlintest – в init
lambdas создаются, а не запускаются. Таким образом, вы не lateinit var
доступ к вашему lateinit var
s в блоке init
. У них просто нет никакой ценности.
Это не работает из-за ошибки в kotlintest, описанной (и фактически почти разрешенной) здесь: https://github.com/kotlintest/kotlintest/issues/174
Короче – interceptTestCase
вызывается в разных экземплярах класса, чем в реальных тестах. Таким образом, это не влияет на ваши тесты вообще.
override val oneInstancePerTest = false
является переопределение свойства: override val oneInstancePerTest = false
Тогда есть только один экземпляр и interceptTestCase
работает правильно, но вы должны помнить – для всех тестов есть только один экземпляр .
Kotlintest 3.0 будет свободен от этой ошибки. (Но, возможно, по умолчанию может быть один экземпляр для всех тестов.)
lateinit vars
как они были инициализированы, вам не следует обращаться к lateinit vars
.
Проблема в том, что вы lateinit var
доступ к вашему lateinit var
s внутри блока init {}
, который по умолчанию является конструктором и вызывается перед interceptTestCase()
.
Самый простой способ – просто сделать mockDocument
и mockProperty
.
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 } } }