Использование Mockk для имитации приватной функции, которая принимает лямбду - PullRequest
1 голос
/ 16 февраля 2020

Я пытаюсь написать модульный тест для реализации абстрактного класса, который я написал. Метод, который я пытаюсь смоделировать, использует лямбду, поскольку это единственный параметр. Я пытаюсь захватить эту лямбду, чтобы я мог вызвать ее и получить результат.

Это метод, который я пытаюсь смоделировать:

protected fun update(block: suspend S.() -> S?): Unit

Я использую расширение Функция в моих тестах выглядит следующим образом:

suspend inline fun <reified T : Model<S>, S : State> T.blah(
    state: S,
    block: (T) -> Unit
): S? {
    val spy = spyk(this, recordPrivateCalls = true)
    val slot = slot<suspend S.() -> S?>()
    every { spy["update"](capture(slot)) } answers { Unit }

    block(spy)
    return slot.captured.invoke(state)
}

Итак, я создаю шпиона, затем слот, а затем, когда вызывается функция обновления, захватывает его, чтобы он блокировал фактический класс от выполнения вызова. Затем я сам вызываю лямбду и возвращаю значение.

Однако я продолжаю получать эту ошибку:

io.mockk.MockKException: не удается найти обновление функции (kotlin. jvm.functions. Function2$Subclass1@6bfa228c) для динамического c вызова

по адресу io.mockk.InternalPlatformDsl.dynamicCall (InternalPlatformDsl.kt: 122) по адресу io.mockk.MockKMatcherScope $ DynamicCall.invoke (API.kt: 1969)

Я следил за трассировкой стека и установил точку останова в классе InternalPlatformDsl.kt и отследил ее до этого блока кода:

for ((idx, param) in it.parameters.withIndex()) {
    val classifier = param.type.classifier
    val matches = when (classifier) {
        is KClass<*> -> classifier.isInstance(params[idx])
        is KTypeParameter -> classifier.upperBounds.anyIsInstance(params[idx])
        else -> false
    }

    if (!matches) {
       return@firstOrNull false
    }
}

Он успешно соответствует первому параметру который является тестируемым классом Model в этом случае, но он не соответствует второму параметру, потому что он включен в функцию capture.

Есть какие-нибудь идеи о том, как я могу перехватить этот вызов update?

Я использую последнюю версию mockk и JUnit 4

...