Перехватчик Kotlintest и латинитовые вары

80
9

У меня есть несколько тестовых тегов, которые имеют общую настройку. Все они нуждаются в двух полях, которые могут быть инициализированы одинаково. Поэтому я думал, что могу извлечь их в полях 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 я вижу, что он выполняется перед тестом и что свойства инициализируются. Затем я перехожу к тесту, и в нем свойства уже не инициализируются.

спросил(а) 2021-01-27T18:30:55+03:00 8 месяцев, 3 недели назад
1
Решение
66

Ответ Клауса Шварц неверен. Это не то, как работает kotlintest - в init lambdas создаются, а не запускаются. Таким образом, вы не lateinit var доступ к вашему lateinit var в блоке init. У них просто нет никакой ценности.

Это не работает из-за ошибки в kotlintest, описанной (и фактически почти разрешенной) здесь: https://github.com/kotlintest/kotlintest/issues/174

Короче - interceptTestCase вызывается в разных экземплярах класса, чем в реальных тестах. Таким образом, это не влияет на ваши тесты вообще.

override val oneInstancePerTest = false является переопределение свойства: override val oneInstancePerTest = false

Тогда есть только один экземпляр и interceptTestCase работает правильно, но вы должны помнить - для всех тестов есть только один экземпляр.

Kotlintest 3.0 будет свободен от этой ошибки. (Но, возможно, по умолчанию может быть один экземпляр для всех тестов.)

ответил(а) 2021-01-27T18:30:55+03:00 8 месяцев, 3 недели назад
47

lateinit vars как они были инициализированы, вам не следует обращаться к lateinit vars.

Проблема заключается в том, что вы lateinit var доступ к вашему lateinit var внутри блока 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
}
}
}

ответил(а) 2021-01-27T18:30:55+03:00 8 месяцев, 3 недели назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема